Lazy loading for a leaderboards in redesign was implemented
This commit is contained in:
parent
a2a85ce151
commit
c3214f5ba9
|
@ -150,7 +150,11 @@ class TetraLeague {
|
||||||
apm ?? 0,
|
apm ?? 0,
|
||||||
pps ?? 0,
|
pps ?? 0,
|
||||||
vs ?? 0,
|
vs ?? 0,
|
||||||
decaying);
|
decaying,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
Duration(seconds: -1),
|
||||||
|
-1);
|
||||||
|
|
||||||
num? getStatByEnum(Stats stat){
|
num? getStatByEnum(Stats stat){
|
||||||
switch (stat) {
|
switch (stat) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// ignore_for_file: hash_and_equals
|
// ignore_for_file: hash_and_equals
|
||||||
|
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:tetra_stats/data_objects/est_tr.dart';
|
import 'package:tetra_stats/data_objects/est_tr.dart';
|
||||||
import 'package:tetra_stats/data_objects/nerd_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/playstyle.dart';
|
||||||
|
@ -27,6 +29,10 @@ class TetrioPlayerFromLeaderboard {
|
||||||
late NerdStats nerdStats;
|
late NerdStats nerdStats;
|
||||||
late EstTr estTr;
|
late EstTr estTr;
|
||||||
late Playstyle playstyle;
|
late Playstyle playstyle;
|
||||||
|
late int gamesPlayedTotal;
|
||||||
|
late int gamesWonTotal;
|
||||||
|
late Duration playtime;
|
||||||
|
late int ar;
|
||||||
|
|
||||||
TetrioPlayerFromLeaderboard(
|
TetrioPlayerFromLeaderboard(
|
||||||
this.userId,
|
this.userId,
|
||||||
|
@ -46,13 +52,19 @@ class TetrioPlayerFromLeaderboard {
|
||||||
this.apm,
|
this.apm,
|
||||||
this.pps,
|
this.pps,
|
||||||
this.vs,
|
this.vs,
|
||||||
this.decaying){
|
this.decaying,
|
||||||
|
this.gamesPlayedTotal,
|
||||||
|
this.gamesWonTotal,
|
||||||
|
this.playtime,
|
||||||
|
this.ar){
|
||||||
nerdStats = NerdStats(apm, pps, vs);
|
nerdStats = NerdStats(apm, pps, vs);
|
||||||
estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
||||||
playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank);
|
playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank);
|
||||||
}
|
}
|
||||||
|
|
||||||
double get winrate => gamesWon / gamesPlayed;
|
double get winrate => gamesWon / gamesPlayed;
|
||||||
|
double get winrateTotal => gamesWonTotal / gamesWonTotal;
|
||||||
|
double get level => pow((xp / 500), 0.6) + (xp / (5000 + (max(0, xp - 4 * pow(10, 6)) / 5000))) + 1;
|
||||||
double get esttracc => estTr.esttr - tr;
|
double get esttracc => estTr.esttr - tr;
|
||||||
double get s1tr => gxe * 250;
|
double get s1tr => gxe * 250;
|
||||||
|
|
||||||
|
@ -66,7 +78,7 @@ class TetrioPlayerFromLeaderboard {
|
||||||
gamesPlayed = json['league']['gamesplayed'] as int;
|
gamesPlayed = json['league']['gamesplayed'] as int;
|
||||||
gamesWon = json['league']['gameswon'] as int;
|
gamesWon = json['league']['gameswon'] as int;
|
||||||
tr = json['league']['tr'] != null ? json['league']['tr'].toDouble() : 0;
|
tr = json['league']['tr'] != null ? json['league']['tr'].toDouble() : 0;
|
||||||
gxe = json['league']['gxe']??-1;
|
gxe = json['league']['gxe']?.toDouble();
|
||||||
glicko = json['league']['glicko']?.toDouble();
|
glicko = json['league']['glicko']?.toDouble();
|
||||||
rd = json['league']['rd']?.toDouble();
|
rd = json['league']['rd']?.toDouble();
|
||||||
rank = json['league']['rank'];
|
rank = json['league']['rank'];
|
||||||
|
@ -75,6 +87,10 @@ class TetrioPlayerFromLeaderboard {
|
||||||
pps = json['league']['pps'] != null ? json['league']['pps'].toDouble() : 0.00;
|
pps = json['league']['pps'] != null ? json['league']['pps'].toDouble() : 0.00;
|
||||||
vs = json['league']['vs'] != null ? json['league']['vs'].toDouble(): 0.00;
|
vs = json['league']['vs'] != null ? json['league']['vs'].toDouble(): 0.00;
|
||||||
decaying = json['league']['decaying'];
|
decaying = json['league']['decaying'];
|
||||||
|
gamesPlayedTotal = json['gamesplayed'] as int;
|
||||||
|
gamesWonTotal = json['gameswon'] as int;
|
||||||
|
playtime = Duration(microseconds: (json['gametime'].toDouble() * 1000000).floor());
|
||||||
|
ar = json['ar'];
|
||||||
nerdStats = NerdStats(apm, pps, vs);
|
nerdStats = NerdStats(apm, pps, vs);
|
||||||
estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
||||||
playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank);
|
playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank);
|
||||||
|
|
|
@ -798,34 +798,60 @@ class TetrioService extends DB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream<TetrioPlayersLeaderboard> fetchFullLeaderboard() async* {
|
Future<List<TetrioPlayerFromLeaderboard>> fetchTetrioLeaderboard({double? after, String? lb}) async {
|
||||||
// late double after;
|
const int lbLength = 100;
|
||||||
// int lbLength = 100;
|
// TetrioPlayersLeaderboard? cached = _cache.get("league", TetrioPlayersLeaderboard);
|
||||||
// TetrioPlayersLeaderboard leaderboard = await fetchTLLeaderboard();
|
// if (cached != null) return cached;
|
||||||
// after = leaderboard.leaderboard.last.tr;
|
|
||||||
// while (lbLength == 100){
|
|
||||||
// TetrioPlayersLeaderboard pseudoLb = await fetchTLLeaderboard(after: after);
|
|
||||||
// leaderboard.addPlayers(pseudoLb.leaderboard);
|
|
||||||
// lbLength = pseudoLb.leaderboard.length;
|
|
||||||
// after = pseudoLb.leaderboard.last.tr;
|
|
||||||
// yield leaderboard;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// i want to know progress, so i trying to figure out this thing:
|
Uri url;
|
||||||
// Stream<TetrioPlayersLeaderboard> fetchTLLeaderboardAsStream() async {
|
if (kIsWeb) {
|
||||||
// TetrioPlayersLeaderboard? cached = _cache.get("league", TetrioPlayersLeaderboard);
|
url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLLeaderboard"});
|
||||||
// if (cached != null) return cached;
|
} else {
|
||||||
|
url = Uri.https('ch.tetr.io', 'api/users/by/${lb??"league"}', {
|
||||||
|
"limit": "100",
|
||||||
|
if (after != null && after != -1) "after": "$after:0:0"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
final response = await client.get(url);
|
||||||
|
|
||||||
// Uri url;
|
switch (response.statusCode) {
|
||||||
// if (kIsWeb) {
|
case 200:
|
||||||
// url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLLeaderboard"});
|
_lbPositions.clear();
|
||||||
// } else {
|
var rawJson = jsonDecode(response.body);
|
||||||
// url = Uri.https('ch.tetr.io', 'api/users/lists/league/all');
|
if (rawJson['success']) { // if api confirmed that everything ok
|
||||||
// }
|
List<TetrioPlayerFromLeaderboard> leaderboard = [];
|
||||||
|
for (Map<String, dynamic> entry in rawJson['data']['entries']) {
|
||||||
// Stream<TetrioPlayersLeaderboard> stream = http.StreamedRequest("GET", url);
|
leaderboard.add(TetrioPlayerFromLeaderboard.fromJson(entry, DateTime.fromMillisecondsSinceEpoch(rawJson['cache']['cached_at'])));
|
||||||
// }
|
}
|
||||||
|
developer.log("fetchTLLeaderboard: Leaderboard retrieved and cached", name: "services/tetrio_crud");
|
||||||
|
//_leaderboardsCache[rawJson['cache']['cached_until'].toString()] = leaderboard;
|
||||||
|
//_cache.store(leaderboard, rawJson['cache']['cached_until']);
|
||||||
|
return leaderboard;
|
||||||
|
} else { // idk how to hit that one
|
||||||
|
developer.log("fetchTLLeaderboard: Bruh", name: "services/tetrio_crud", error: rawJson);
|
||||||
|
throw Exception("Failed to get leaderboard (problems on the tetr.io side)"); // will it be on tetr.io side?
|
||||||
|
}
|
||||||
|
case 403:
|
||||||
|
throw TetrioForbidden();
|
||||||
|
case 429:
|
||||||
|
throw TetrioTooManyRequests();
|
||||||
|
case 418:
|
||||||
|
throw TetrioOskwareBridgeProblem();
|
||||||
|
case 500:
|
||||||
|
case 502:
|
||||||
|
case 503:
|
||||||
|
case 504:
|
||||||
|
throw TetrioInternalProblem();
|
||||||
|
default:
|
||||||
|
developer.log("fetchTLLeaderboard: Failed to fetch leaderboard", name: "services/tetrio_crud", error: response.statusCode);
|
||||||
|
throw ConnectionIssue(response.statusCode, response.reasonPhrase??"No reason");
|
||||||
|
}
|
||||||
|
} on http.ClientException catch (e, s) {
|
||||||
|
developer.log("$e, $s");
|
||||||
|
throw http.ClientException(e.message, e.uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TetrioPlayersLeaderboard? getCachedLeaderboard(){
|
TetrioPlayersLeaderboard? getCachedLeaderboard(){
|
||||||
return _cache.get("league", TetrioPlayersLeaderboard);
|
return _cache.get("league", TetrioPlayersLeaderboard);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart' hide Badge;
|
import 'package:flutter/material.dart' hide Badge;
|
||||||
|
@ -207,6 +209,23 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DestinationCutoffs extends StatefulWidget{
|
||||||
|
final BoxConstraints constraints;
|
||||||
|
|
||||||
|
const DestinationCutoffs({super.key, required this.constraints});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DestinationLeaderboards> createState() => _DestinationCutoffsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DestinationCutoffsState extends State<DestinationLeaderboards> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// TODO: implement build
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DestinationLeaderboards extends StatefulWidget{
|
class DestinationLeaderboards extends StatefulWidget{
|
||||||
final BoxConstraints constraints;
|
final BoxConstraints constraints;
|
||||||
|
|
||||||
|
@ -216,10 +235,72 @@ class DestinationLeaderboards extends StatefulWidget{
|
||||||
State<DestinationLeaderboards> createState() => _DestinationLeaderboardsState();
|
State<DestinationLeaderboards> createState() => _DestinationLeaderboardsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Leaderboards{
|
||||||
|
tl,
|
||||||
|
xp,
|
||||||
|
ar
|
||||||
|
}
|
||||||
|
|
||||||
class _DestinationLeaderboardsState extends State<DestinationLeaderboards> {
|
class _DestinationLeaderboardsState extends State<DestinationLeaderboards> {
|
||||||
Cards rightCard = Cards.tetraLeague;
|
|
||||||
//Duration postSeasonLeft = seasonStart.difference(DateTime.now());
|
//Duration postSeasonLeft = seasonStart.difference(DateTime.now());
|
||||||
final List<String> leaderboards = ["Tetra League", "Quick Play", "Quick Play Expert"];
|
final Map<Leaderboards, String> leaderboards = {Leaderboards.tl: "Tetra League", Leaderboards.xp: "XP", Leaderboards.ar: "Acievement Points"};
|
||||||
|
Leaderboards _currentLb = Leaderboards.tl;
|
||||||
|
final StreamController<List<TetrioPlayerFromLeaderboard>> _dataStreamController = StreamController<List<TetrioPlayerFromLeaderboard>>();
|
||||||
|
late final ScrollController _scrollController;
|
||||||
|
Stream<List<TetrioPlayerFromLeaderboard>> get dataStream => _dataStreamController.stream;
|
||||||
|
List<TetrioPlayerFromLeaderboard> list = [];
|
||||||
|
bool _isFetchingData = false;
|
||||||
|
double after = 25000.00;
|
||||||
|
|
||||||
|
Future<void> _fetchData() async {
|
||||||
|
if (_isFetchingData) {
|
||||||
|
// Avoid fetching new data while already fetching
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
_isFetchingData = true;
|
||||||
|
setState(() {});
|
||||||
|
|
||||||
|
final items = switch(_currentLb){
|
||||||
|
Leaderboards.tl => await teto.fetchTetrioLeaderboard(after: after),
|
||||||
|
Leaderboards.xp => await teto.fetchTetrioLeaderboard(after: after, lb: "xp"),
|
||||||
|
Leaderboards.ar => await teto.fetchTetrioLeaderboard(after: after, lb: "ar"),
|
||||||
|
};
|
||||||
|
|
||||||
|
list.addAll(items);
|
||||||
|
|
||||||
|
_dataStreamController.add(list);
|
||||||
|
after = switch (_currentLb){
|
||||||
|
Leaderboards.tl => list.last.tr,
|
||||||
|
Leaderboards.xp => list.last.xp,
|
||||||
|
Leaderboards.ar => list.last.ar.toDouble(),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
_dataStreamController.addError(e);
|
||||||
|
} finally {
|
||||||
|
// Set to false when data fetching is complete
|
||||||
|
_isFetchingData = false;
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_scrollController = ScrollController();
|
||||||
|
_fetchData();
|
||||||
|
_scrollController.addListener(() {
|
||||||
|
_scrollController.addListener(() {
|
||||||
|
final maxScroll = _scrollController.position.maxScrollExtent;
|
||||||
|
final currentScroll = _scrollController.position.pixels;
|
||||||
|
|
||||||
|
if (currentScroll == maxScroll) {
|
||||||
|
// When the last item is fully visible, load the next page.
|
||||||
|
_fetchData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -247,7 +328,17 @@ class _DestinationLeaderboardsState extends State<DestinationLeaderboards> {
|
||||||
return Card(
|
return Card(
|
||||||
surfaceTintColor: theme.colorScheme.primary,
|
surfaceTintColor: theme.colorScheme.primary,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(leaderboards[index]),
|
title: Text(leaderboards.values.elementAt(index)),
|
||||||
|
onTap: () {
|
||||||
|
_currentLb = leaderboards.keys.elementAt(index);
|
||||||
|
list.clear();
|
||||||
|
after = switch (_currentLb){
|
||||||
|
Leaderboards.tl => 25000.00,
|
||||||
|
Leaderboards.xp => -1.00,
|
||||||
|
Leaderboards.ar => -1.00,
|
||||||
|
};
|
||||||
|
_fetchData();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -258,11 +349,45 @@ class _DestinationLeaderboardsState extends State<DestinationLeaderboards> {
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: widget.constraints.maxWidth - 350 - 88,
|
width: widget.constraints.maxWidth - 350 - 88,
|
||||||
child: const Card(
|
child: Card(
|
||||||
child: Column(
|
child: StreamBuilder<List<TetrioPlayerFromLeaderboard>>(
|
||||||
children: [
|
stream: dataStream,
|
||||||
|
builder:(context, snapshot) {
|
||||||
],
|
switch (snapshot.connectionState){
|
||||||
|
case ConnectionState.none:
|
||||||
|
case ConnectionState.waiting:
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
case ConnectionState.active:
|
||||||
|
case ConnectionState.done:
|
||||||
|
if (snapshot.hasData){
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Text(leaderboards[_currentLb]!, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
|
||||||
|
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: _scrollController,
|
||||||
|
itemCount: list.length,
|
||||||
|
itemBuilder: (BuildContext context, int index){
|
||||||
|
return ListTile(
|
||||||
|
leading: Text(intf.format(index+1)),
|
||||||
|
title: Text(snapshot.data![index].username),
|
||||||
|
trailing: Text(switch (_currentLb){
|
||||||
|
Leaderboards.tl => f2.format(snapshot.data![index].tr),
|
||||||
|
Leaderboards.xp => f2.format(snapshot.data![index].level),
|
||||||
|
Leaderboards.ar => intf.format(snapshot.data![index].ar),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (snapshot.hasError){ return FutureError(snapshot); }
|
||||||
|
}
|
||||||
|
return Text("huh?");
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -297,13 +422,11 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
late TooltipBehavior _leagueTooltipBehavior;
|
late TooltipBehavior _leagueTooltipBehavior;
|
||||||
String yAxisTitle = "";
|
String yAxisTitle = "";
|
||||||
bool _smooth = false;
|
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"];
|
|
||||||
final List<DropdownMenuItem<Stats>> _yAxis = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuItem(value: e.key, child: Text(e.value))];
|
final List<DropdownMenuItem<Stats>> _yAxis = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuItem(value: e.key, child: Text(e.value))];
|
||||||
Graph _graph = Graph.history;
|
Graph _graph = Graph.history;
|
||||||
Stats _Ychart = Stats.tr;
|
Stats _Ychart = Stats.tr;
|
||||||
Stats _Xchart = Stats.tr;
|
Stats _Xchart = Stats.tr;
|
||||||
int _season = currentSeason-1;
|
int _season = currentSeason-1;
|
||||||
//late List<List<DropdownMenuItem<List<_HistoryChartSpot>>>> historyData;
|
|
||||||
//Duration postSeasonLeft = seasonStart.difference(DateTime.now());
|
//Duration postSeasonLeft = seasonStart.difference(DateTime.now());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -365,7 +488,6 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
animationDuration: 0,
|
animationDuration: 0,
|
||||||
builder: (dynamic data, dynamic point, dynamic series,
|
builder: (dynamic data, dynamic point, dynamic series,
|
||||||
int pointIndex, int seriesIndex) {
|
int pointIndex, int seriesIndex) {
|
||||||
print(point);
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -454,7 +576,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
case ConnectionState.active:
|
case ConnectionState.active:
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
case ConnectionState.done:
|
case ConnectionState.done:
|
||||||
if (snapshot.hasData && snapshot.data!.isNotEmpty){
|
if (snapshot.hasData){
|
||||||
List<_HistoryChartSpot> selectedGraph = snapshot.data![_season][_Ychart]!;
|
List<_HistoryChartSpot> selectedGraph = snapshot.data![_season][_Ychart]!;
|
||||||
yAxisTitle = chartsShortTitles[_Ychart]!;
|
yAxisTitle = chartsShortTitles[_Ychart]!;
|
||||||
return SfCartesianChart(
|
return SfCartesianChart(
|
||||||
|
@ -500,20 +622,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}else{
|
}else{ return FutureError(snapshot); }
|
||||||
return Center(child:
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(snapshot.error.toString(), 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.toString(), textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -546,20 +655,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}else{
|
}else{ return FutureError(snapshot); }
|
||||||
return Center(child:
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(snapshot.error.toString(), 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.toString(), textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -580,9 +676,14 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
return SfCartesianChart(
|
return SfCartesianChart(
|
||||||
tooltipBehavior: _leagueTooltipBehavior,
|
tooltipBehavior: _leagueTooltipBehavior,
|
||||||
zoomPanBehavior: _zoomPanBehavior,
|
zoomPanBehavior: _zoomPanBehavior,
|
||||||
primaryXAxis: _gamesPlayedInsteadOfDateAndTime ? const NumericAxis() : const DateTimeAxis(),
|
primaryXAxis: const DateTimeAxis(),
|
||||||
primaryYAxis: const NumericAxis(
|
primaryYAxis: NumericAxis(
|
||||||
rangePadding: ChartRangePadding.additional,
|
// isInversed: true,
|
||||||
|
maximum: switch (_Ychart){
|
||||||
|
Stats.tr => 25000.0,
|
||||||
|
Stats.gxe => 100.00,
|
||||||
|
_ => null
|
||||||
|
},
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.all(0),
|
margin: const EdgeInsets.all(0),
|
||||||
series: <CartesianSeries>[
|
series: <CartesianSeries>[
|
||||||
|
@ -590,34 +691,18 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
enableTooltip: true,
|
enableTooltip: true,
|
||||||
dataSource: snapshot.data,
|
dataSource: snapshot.data,
|
||||||
animationDuration: 0,
|
animationDuration: 0,
|
||||||
//opacity: _smooth ? 0 : 1,
|
//opacity: 0.5,
|
||||||
xValueMapper: (Cutoffs data, _) => data.ts,
|
xValueMapper: (Cutoffs data, _) => data.ts,
|
||||||
yValueMapper: (Cutoffs data, _) => data.tr[rank],
|
yValueMapper: (Cutoffs data, _) => switch (_Ychart){
|
||||||
color: rankColors[rank],
|
Stats.glicko => data.glicko[rank],
|
||||||
// trendlines:<Trendline>[
|
Stats.gxe => data.gxe[rank],
|
||||||
// Trendline(
|
_ => data.tr[rank]
|
||||||
// isVisible: _smooth,
|
},
|
||||||
// period: (selectedGraph.length/175).floor(),
|
color: rankColors[rank]!
|
||||||
// type: TrendlineType.movingAverage,
|
|
||||||
// color: Theme.of(context).colorScheme.primary)
|
|
||||||
// ],
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}else{
|
}else{ return FutureError(snapshot); }
|
||||||
return Center(child:
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(snapshot.error.toString(), 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.toString(), textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -679,7 +764,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
|
||||||
children: [
|
children: [
|
||||||
const Padding(padding: EdgeInsets.all(8.0), child: Text("Y:", style: TextStyle(fontSize: 22))),
|
const Padding(padding: EdgeInsets.all(8.0), child: Text("Y:", style: TextStyle(fontSize: 22))),
|
||||||
DropdownButton<Stats>(
|
DropdownButton<Stats>(
|
||||||
items: _yAxis,
|
items: _graph == Graph.leagueCutoffs ? [DropdownMenuItem(value: Stats.tr, child: Text(chartsShortTitles[Stats.tr]!)), DropdownMenuItem(value: Stats.glicko, child: Text(chartsShortTitles[Stats.glicko]!)), DropdownMenuItem(value: Stats.gxe, child: Text(chartsShortTitles[Stats.gxe]!))] : _yAxis,
|
||||||
value: _Ychart,
|
value: _Ychart,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -1254,20 +1339,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (snapshot.hasError){
|
if (snapshot.hasError){ return FutureError(snapshot); }
|
||||||
return Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(t.errors.noSuchUser, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
|
||||||
child: Text(t.errors.noSuchUserSub, textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return const Text("what?");
|
return const Text("what?");
|
||||||
},
|
},
|
||||||
|
@ -1306,20 +1378,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (snapshot.hasError){
|
if (snapshot.hasError){ return FutureError(snapshot); }
|
||||||
return Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(t.errors.noSuchUser, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
|
||||||
child: Text(t.errors.noSuchUserSub, textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return const Text("what?");
|
return const Text("what?");
|
||||||
},
|
},
|
||||||
|
@ -1366,20 +1425,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
|
||||||
if (snapshot.hasData){
|
if (snapshot.hasData){
|
||||||
return SizedBox(height: constraints.maxHeight - 145, child: _TLRecords(userID: widget.searchFor, changePlayer: (){}, data: snapshot.data!.records, wasActiveInTL: snapshot.data!.records.isNotEmpty, oldMathcesHere: false));
|
return SizedBox(height: constraints.maxHeight - 145, child: _TLRecords(userID: widget.searchFor, changePlayer: (){}, data: snapshot.data!.records, wasActiveInTL: snapshot.data!.records.isNotEmpty, oldMathcesHere: false));
|
||||||
}
|
}
|
||||||
if (snapshot.hasError){
|
if (snapshot.hasError){ return FutureError(snapshot); }
|
||||||
return Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(t.errors.noSuchUser, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
|
||||||
child: Text(t.errors.noSuchUserSub, textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return const Text("what?");
|
return const Text("what?");
|
||||||
},
|
},
|
||||||
|
@ -1760,20 +1806,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
|
||||||
case ConnectionState.active:
|
case ConnectionState.active:
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
case ConnectionState.done:
|
case ConnectionState.done:
|
||||||
if (snapshot.hasError){
|
if (snapshot.hasError){ return FutureError(snapshot); }
|
||||||
return Center(child:
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(snapshot.error.toString(), 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.toString(), textAlign: TextAlign.center),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (snapshot.hasData){
|
if (snapshot.hasData){
|
||||||
blitzBetterThanRankAverage = (snapshot.data!.summaries!.league.rank != "z" && snapshot.data!.summaries!.blitz != null && snapshot.data!.summaries!.league.rank != "x+") ? snapshot.data!.summaries!.blitz!.stats.score > blitzAverages[snapshot.data!.summaries!.league.rank]! : null;
|
blitzBetterThanRankAverage = (snapshot.data!.summaries!.league.rank != "z" && snapshot.data!.summaries!.blitz != null && snapshot.data!.summaries!.league.rank != "x+") ? snapshot.data!.summaries!.blitz!.stats.score > blitzAverages[snapshot.data!.summaries!.league.rank]! : null;
|
||||||
sprintBetterThanRankAverage = (snapshot.data!.summaries!.league.rank != "z" && snapshot.data!.summaries!.sprint != null && snapshot.data!.summaries!.league.rank != "x+") ? snapshot.data!.summaries!.sprint!.stats.finalTime < sprintAverages[snapshot.data!.summaries!.league.rank]! : null;
|
sprintBetterThanRankAverage = (snapshot.data!.summaries!.league.rank != "z" && snapshot.data!.summaries!.sprint != null && snapshot.data!.summaries!.league.rank != "x+") ? snapshot.data!.summaries!.sprint!.stats.finalTime < sprintAverages[snapshot.data!.summaries!.league.rank]! : null;
|
||||||
|
@ -1837,13 +1870,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
|
||||||
case ConnectionState.done:
|
case ConnectionState.done:
|
||||||
if (snapshot.hasData){
|
if (snapshot.hasData){
|
||||||
return NewsThingy(snapshot.data!);
|
return NewsThingy(snapshot.data!);
|
||||||
}else if (snapshot.hasError){
|
}else if (snapshot.hasError){ return FutureError(snapshot); }
|
||||||
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 const Text("what?");
|
return const Text("what?");
|
||||||
}
|
}
|
||||||
|
@ -3319,3 +3346,25 @@ class TLRatingThingy extends StatelessWidget{
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FutureError extends StatelessWidget{
|
||||||
|
final AsyncSnapshot snapshot;
|
||||||
|
|
||||||
|
FutureError(this.snapshot);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(child:
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(snapshot.error.toString(), 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.toString(), textAlign: TextAlign.center),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue