default profile and comparing with averages in TL are now work

This commit is contained in:
dan63047 2024-10-23 01:28:55 +03:00
parent c12d450884
commit b8a8ddf0c9
6 changed files with 153 additions and 79 deletions

View File

@ -38,7 +38,7 @@ jobs:
discussionCategory: autobuilded-releases discussionCategory: autobuilded-releases
artifacts: "build/windows/x64/runner/Release/TetraStats-${{github.ref_name}}-windows.zip" artifacts: "build/windows/x64/runner/Release/TetraStats-${{github.ref_name}}-windows.zip"
tag: Auto-${{ github.run_number }} tag: Auto-${{ github.run_number }}
body: Builded with GitHub Action workflow body: Build with GitHub Action workflow
token: ${{ secrets.TOKEN }} token: ${{ secrets.TOKEN }}
build-and-release-linux: build-and-release-linux:
name: Build Linux App name: Build Linux App
@ -71,7 +71,7 @@ jobs:
discussionCategory: autobuilded-releases discussionCategory: autobuilded-releases
artifacts: "build/linux/x64/release/bundle/TetraStats-${{github.ref_name}}-linux.zip" artifacts: "build/linux/x64/release/bundle/TetraStats-${{github.ref_name}}-linux.zip"
tag: Auto-${{ github.run_number }} tag: Auto-${{ github.run_number }}
body: Builded with GitHub Action workflow body: Build with GitHub Action workflow
token: ${{ secrets.TOKEN }} token: ${{ secrets.TOKEN }}
# build-and-release-android: # build-and-release-android:
# name: Build Android App # name: Build Android App
@ -96,5 +96,5 @@ jobs:
# discussionCategory: autobuilded-releases # discussionCategory: autobuilded-releases
# artifacts: "build/app/outputs/flutter-apk/*" # artifacts: "build/app/outputs/flutter-apk/*"
# tag: Auto-${{ github.run_number }} # tag: Auto-${{ github.run_number }}
# body: Builded with GitHub Action workflow # body: Build with GitHub Action workflow
# token: ${{ secrets.TOKEN }} # token: ${{ secrets.TOKEN }}

View File

@ -1,4 +1,4 @@
// ignore_for_file: hash_and_equals import 'package:tetra_stats/data_objects/nerd_stats.dart';
class CutoffTetrio { class CutoffTetrio {
late int pos; late int pos;
@ -8,6 +8,7 @@ class CutoffTetrio {
late double? apm; late double? apm;
late double? pps; late double? pps;
late double? vs; late double? vs;
NerdStats? nerdStats;
late int count; late int count;
late double countPercentile; late double countPercentile;
@ -21,7 +22,9 @@ class CutoffTetrio {
required this.vs, required this.vs,
required this.count, required this.count,
required this.countPercentile required this.countPercentile
}); }){
if (apm != null && pps != null && vs != null) nerdStats = NerdStats(apm!, pps!, vs!);
}
CutoffTetrio.fromJson(Map<String, dynamic> json, int total){ CutoffTetrio.fromJson(Map<String, dynamic> json, int total){
pos = json['pos']; pos = json['pos'];
@ -33,6 +36,7 @@ class CutoffTetrio {
vs = json['vs']?.toDouble(); vs = json['vs']?.toDouble();
count = json['count']; count = json['count'];
countPercentile = count / total; countPercentile = count / total;
if (apm != null && pps != null && vs != null) nerdStats = NerdStats(apm!, pps!, vs!);
} }
} }

View File

@ -9,6 +9,16 @@ Color getColorOfRank(int rank){
return Colors.grey; return Colors.grey;
} }
Color? getStatColor(num value, num? avgValue, bool higherIsBetter){
if (avgValue == null) return null;
num percentile = (higherIsBetter ? value / avgValue : avgValue / value).abs();
if (percentile > 1.50) return Colors.purpleAccent;
if (percentile > 1.20) return Colors.blueAccent;
if (percentile > 0.90) return Colors.greenAccent;
if (percentile > 0.70) return Colors.yellowAccent;
return Colors.redAccent;
}
Color getDifferenceColor(num diff){ Color getDifferenceColor(num diff){
return diff.isNegative ? Colors.redAccent : Colors.greenAccent; return diff.isNegative ? Colors.redAccent : Colors.greenAccent;
} }

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:tetra_stats/data_objects/cutoff_tetrio.dart';
import 'package:tetra_stats/data_objects/news.dart'; import 'package:tetra_stats/data_objects/news.dart';
import 'package:tetra_stats/data_objects/p1nkl0bst3r.dart'; import 'package:tetra_stats/data_objects/p1nkl0bst3r.dart';
import 'package:tetra_stats/data_objects/record_extras.dart'; import 'package:tetra_stats/data_objects/record_extras.dart';
@ -44,10 +45,11 @@ class FetchResults{
List<TetraLeague> states; List<TetraLeague> states;
Summaries? summaries; Summaries? summaries;
Cutoffs? cutoffs; Cutoffs? cutoffs;
CutoffsTetrio? averages;
bool isTracked; bool isTracked;
Exception? exception; Exception? exception;
FetchResults(this.success, this.player, this.states, this.summaries, this.cutoffs, this.isTracked, this.exception); FetchResults(this.success, this.player, this.states, this.summaries, this.cutoffs, this.averages, this.isTracked, this.exception);
} }
class RecordSummary extends StatelessWidget{ class RecordSummary extends StatelessWidget{
@ -128,9 +130,10 @@ class RecordSummary extends StatelessWidget{
class LeagueCard extends StatelessWidget{ class LeagueCard extends StatelessWidget{
final TetraLeague league; final TetraLeague league;
final CutoffTetrio? averages;
final bool showSeasonNumber; final bool showSeasonNumber;
const LeagueCard({super.key, required this.league, this.showSeasonNumber = false}); const LeagueCard({super.key, required this.league, this.averages, this.showSeasonNumber = false});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -157,7 +160,20 @@ class LeagueCard extends StatelessWidget{
const Divider(), const Divider(),
TLRatingThingy(userID: "", tlData: league, showPositions: true), TLRatingThingy(userID: "", tlData: league, showPositions: true),
const Divider(), const Divider(),
Text("${league.apm != null ? f2.format(league.apm) : "-.--"} APM • ${league.pps != null ? f2.format(league.pps) : "-.--"} PPS • ${league.vs != null ? f2.format(league.vs) : "-.--"} VS • ${league.nerdStats != null ? f2.format(league.nerdStats!.app) : "-.--"} APP • ${league.nerdStats != null ? f2.format(league.nerdStats!.vsapm) : "-.--"} VS/APM", style: const TextStyle(color: Colors.grey)) RichText(text: TextSpan(
style: const TextStyle(fontFamily: "Eurostile Round", color: Colors.grey),
children: [
TextSpan(text: "${league.apm != null ? f2.format(league.apm) : "-.--"} APM", style: TextStyle(color: league.apm != null ? getStatColor(league.apm!, averages?.apm, true) : null)),
TextSpan(text: ""),
TextSpan(text: "${league.pps != null ? f2.format(league.pps) : "-.--"} PPS", style: TextStyle(color: league.pps != null ? getStatColor(league.pps!, averages?.pps, true) : null)),
TextSpan(text: ""),
TextSpan(text: "${league.vs != null ? f2.format(league.vs) : "-.--"} VS", style: TextStyle(color: league.vs != null ? getStatColor(league.vs!, averages?.vs, true) : null)),
TextSpan(text: ""),
TextSpan(text: "${league.nerdStats != null ? f2.format(league.nerdStats!.app) : "-.--"} APP", style: TextStyle(color: league.nerdStats != null ? getStatColor(league.nerdStats!.app, averages?.nerdStats?.app, true) : null)),
TextSpan(text: ""),
TextSpan(text: "${league.nerdStats != null ? f2.format(league.nerdStats!.vsapm) : "-.--"} VS/APM", style: TextStyle(color: league.nerdStats != null ? getStatColor(league.nerdStats!.vsapm, averages?.nerdStats?.vsapm, true) : null)),
]
)),
], ],
), ),
), ),
@ -181,7 +197,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
bool? sprintBetterThanRankAverage; bool? sprintBetterThanRankAverage;
bool? blitzBetterThanRankAverage; bool? blitzBetterThanRankAverage;
Widget getOverviewCard(Summaries summaries){ Widget getOverviewCard(Summaries summaries, CutoffTetrio? averages){
return Column( return Column(
children: [ children: [
const Card( const Card(
@ -198,7 +214,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
), ),
), ),
), ),
LeagueCard(league: summaries.league), LeagueCard(league: summaries.league, averages: averages),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -373,7 +389,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
); );
} }
Widget getTetraLeagueCard(TetraLeague data, Cutoffs? cutoffs, List<TetraLeague> states){ Widget getTetraLeagueCard(TetraLeague data, Cutoffs? cutoffs, CutoffTetrio? averages, List<TetraLeague> states){
TetraLeague? toCompare = states.length >= 2 ? states.elementAtOrNull(states.length-2) : null; TetraLeague? toCompare = states.length >= 2 ? states.elementAtOrNull(states.length-2) : null;
return Column( return Column(
children: [ children: [
@ -393,7 +409,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
), ),
), ),
), ),
TetraLeagueThingy(league: data, toCompare: toCompare, cutoffs: cutoffs), TetraLeagueThingy(league: data, toCompare: toCompare, cutoffs: cutoffs, averages: averages),
if (data.nerdStats != null) Card( if (data.nerdStats != null) Card(
//surfaceTintColor: rankColors[data.rank], //surfaceTintColor: rankColors[data.rank],
child: Row( child: Row(
@ -405,7 +421,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
], ],
), ),
), ),
if (data.nerdStats != null) NerdStatsThingy(nerdStats: data.nerdStats!, oldNerdStats: toCompare?.nerdStats), if (data.nerdStats != null) NerdStatsThingy(nerdStats: data.nerdStats!, oldNerdStats: toCompare?.nerdStats, averages: averages),
if (data.nerdStats != null) GraphsThingy(nerdStats: data.nerdStats!, playstyle: data.playstyle!, apm: data.apm!, pps: data.pps!, vs: data.vs!) if (data.nerdStats != null) GraphsThingy(nerdStats: data.nerdStats!, playstyle: data.playstyle!, apm: data.apm!, pps: data.pps!, vs: data.vs!)
], ],
); );
@ -1068,9 +1084,9 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
child: SlideTransition( child: SlideTransition(
position: _offsetAnimation, position: _offsetAnimation,
child: switch (rightCard){ child: switch (rightCard){
Cards.overview => getOverviewCard(snapshot.data!.summaries!), Cards.overview => getOverviewCard(snapshot.data!.summaries!, (snapshot.data!.averages != null && snapshot.data!.summaries!.league.rank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.rank] : (snapshot.data!.averages != null && snapshot.data!.summaries!.league.percentileRank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.rank] : null),
Cards.tetraLeague => switch (cardMod){ Cards.tetraLeague => switch (cardMod){
CardMod.info => getTetraLeagueCard(snapshot.data!.summaries!.league, snapshot.data!.cutoffs, snapshot.data!.states), CardMod.info => getTetraLeagueCard(snapshot.data!.summaries!.league, snapshot.data!.cutoffs, (snapshot.data!.averages != null && snapshot.data!.summaries!.league.rank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.rank] : (snapshot.data!.averages != null && snapshot.data!.summaries!.league.percentileRank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.rank] : null, snapshot.data!.states),
CardMod.ex => getPreviousSeasonsList(snapshot.data!.summaries!.pastLeague), CardMod.ex => getPreviousSeasonsList(snapshot.data!.summaries!.pastLeague),
CardMod.records => getRecentTLrecords(widget.constraints), CardMod.records => getRecentTLrecords(widget.constraints),
_ => const Center(child: Text("huh?")) _ => const Center(child: Text("huh?"))

View File

@ -11,6 +11,7 @@ import 'package:intl/intl.dart';
import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:syncfusion_flutter_gauges/gauges.dart';
import 'package:tetra_stats/data_objects/badge.dart'; import 'package:tetra_stats/data_objects/badge.dart';
import 'package:tetra_stats/data_objects/beta_record.dart'; import 'package:tetra_stats/data_objects/beta_record.dart';
import 'package:tetra_stats/data_objects/cutoff_tetrio.dart';
import 'package:tetra_stats/data_objects/distinguishment.dart'; import 'package:tetra_stats/data_objects/distinguishment.dart';
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';
@ -63,24 +64,32 @@ Future<FetchResults> getData(String searchFor) async {
player = await teto.fetchPlayer(searchFor); // Otherwise it's probably a user id or username player = await teto.fetchPlayer(searchFor); // Otherwise it's probably a user id or username
} }
}on TetrioPlayerNotExist{ }on TetrioPlayerNotExist{
return FetchResults(false, null, [], null, null, false, TetrioPlayerNotExist()); return FetchResults(false, null, [], null, null, null, false, TetrioPlayerNotExist());
} }
late Summaries summaries; late Summaries summaries;
late Cutoffs cutoffs; late Cutoffs cutoffs;
late CutoffsTetrio averages;
try {
List<dynamic> requests = await Future.wait([ List<dynamic> requests = await Future.wait([
teto.fetchSummaries(player.userId), teto.fetchSummaries(player.userId),
teto.fetchCutoffsBeanserver(), teto.fetchCutoffsBeanserver(),
teto.fetchCutoffsTetrio()
]); ]);
List<TetraLeague> states = await teto.getStates(player.userId, season: currentSeason);
summaries = requests[0]; summaries = requests[0];
cutoffs = requests[1]; cutoffs = requests.elementAtOrNull(1);
averages = requests.elementAtOrNull(2);
} on Exception catch (e) {
return FetchResults(false, null, [], null, null, null, false, e);
}
List<TetraLeague> states = await teto.getStates(player.userId, season: currentSeason);
bool isTracking = await teto.isPlayerTracking(player.userId); bool isTracking = await teto.isPlayerTracking(player.userId);
if (isTracking){ // if tracked - save data to local DB if (isTracking){ // if tracked - save data to local DB
await teto.storeState(summaries.league); await teto.storeState(summaries.league);
} }
return FetchResults(true, player, states, summaries, cutoffs, isTracking, null); return FetchResults(true, player, states, summaries, cutoffs, averages, isTracking, null);
} }
class MainView extends StatefulWidget { class MainView extends StatefulWidget {
@ -242,6 +251,7 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
SettingsCardMod mod = SettingsCardMod.general; SettingsCardMod mod = SettingsCardMod.general;
List<DropdownMenuItem<AppLocale>> locales = <DropdownMenuItem<AppLocale>>[]; List<DropdownMenuItem<AppLocale>> locales = <DropdownMenuItem<AppLocale>>[];
String defaultNickname = "Checking..."; String defaultNickname = "Checking...";
String defaultID = "";
late bool oskKagariGimmick; late bool oskKagariGimmick;
late bool sheetbotRadarGraphs; late bool sheetbotRadarGraphs;
late int ratingMode; late int ratingMode;
@ -251,7 +261,11 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
late bool updateInBG; late bool updateInBG;
final TextEditingController _playertext = TextEditingController(); final TextEditingController _playertext = TextEditingController();
late AnimationController _defaultNicknameAnimController; late AnimationController _defaultNicknameAnimController;
late Animation _defaultNicknameAnim; late Animation _goodDefaultNicknameAnim;
late Animation _badDefaultNicknameAnim;
late Animation _defaultNicknameAnim = _goodDefaultNicknameAnim;
double helperTextOpacity = 0;
String helperText = "Press Enter to submit";
@override @override
void initState() { void initState() {
@ -260,17 +274,30 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
// windowManager.setTitle("Tetra Stats: ${t.settings}"); // windowManager.setTitle("Tetra Stats: ${t.settings}");
// } // }
_defaultNicknameAnimController = AnimationController( _defaultNicknameAnimController = AnimationController(
value: 1.0,
duration: Durations.extralong4, duration: Durations.extralong4,
vsync: this, vsync: this,
); );
_defaultNicknameAnim = new Tween( _goodDefaultNicknameAnim = new ColorTween(
begin: 0.0, begin: Colors.greenAccent,
end: 1.0, end: Colors.grey,
).animate(new CurvedAnimation( ).animate(new CurvedAnimation(
parent: _defaultNicknameAnimController, parent: _defaultNicknameAnimController,
curve: Cubic(.15,-0.40,.86,-0.39), curve: Easing.emphasizedAccelerate,
reverseCurve: Cubic(0,.99,.99,1.01) //reverseCurve: Cubic(0,.99,.99,1.01)
)); ))..addStatusListener((status) {
if (status.index == 3) setState((){helperText = "Press Enter to submit"; helperTextOpacity = 0;});
});
_badDefaultNicknameAnim = new ColorTween(
begin: Colors.redAccent,
end: Colors.grey,
).animate(new CurvedAnimation(
parent: _defaultNicknameAnimController,
curve: Easing.emphasizedAccelerate,
//reverseCurve: Cubic(0,.99,.99,1.01)
))..addStatusListener((status) {
if (status.index == 3) setState((){helperText = "Press Enter to submit"; helperTextOpacity = 0;});
});
_getPreferences(); _getPreferences();
super.initState(); super.initState();
} }
@ -289,36 +316,35 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
sheetbotRadarGraphs = prefs.getBool("sheetbotRadarGraphs")?? false; sheetbotRadarGraphs = prefs.getBool("sheetbotRadarGraphs")?? false;
ratingMode = prefs.getInt("ratingMode") ?? 0; ratingMode = prefs.getInt("ratingMode") ?? 0;
timestampMode = prefs.getInt("timestampMode") ?? 0; timestampMode = prefs.getInt("timestampMode") ?? 0;
_setDefaultNickname(prefs.getString("player")); _setDefaultNickname(prefs.getString("player")??"").then((v){setState((){});});
defaultID = prefs.getString("playerID")??"";
} }
Future<bool> _setDefaultNickname(String? n) async { Future<bool> _setDefaultNickname(String n) async {
if (n != null) { if (n.isNotEmpty) {
try { try {
if (n.length > 16){
defaultNickname = await teto.getNicknameByID(n); defaultNickname = await teto.getNicknameByID(n);
await prefs.setString('playerID', n);
}else{
TetrioPlayer player = await teto.fetchPlayer(n);
defaultNickname = player.username;
await prefs.setString('playerID', player.userId);
}
await prefs.setString('player', defaultNickname);
return true; return true;
} on TetrioPlayerNotExist { } catch (e) {
defaultNickname = n;
return false; return false;
} }
} else { } else {
defaultNickname = "dan63047"; defaultNickname = "dan63";
await prefs.setString('player', "dan63");
await prefs.setString('playerID', "6098518e3d5155e6ec429cdc");
return true; return true;
} }
//setState(() {}); //setState(() {});
} }
Future<bool> _setPlayer(String player) async {
bool success = await _setDefaultNickname(player);
if (success) await prefs.setString('player', player);
return success;
}
Future<void> _removePlayer() async {
await prefs.remove('player');
await _setDefaultNickname("6098518e3d5155e6ec429cdc");
}
Widget getGeneralSettings(){ Widget getGeneralSettings(){
return Column( return Column(
children: [ children: [
@ -341,15 +367,30 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
trailing: SizedBox(width: 150.0, child: AnimatedBuilder( trailing: SizedBox(width: 150.0, child: AnimatedBuilder(
animation: _defaultNicknameAnim, animation: _defaultNicknameAnim,
builder: (context, child) { builder: (context, child) {
return TextField( return Focus(
onFocusChange: (value) {
setState((){helperTextOpacity = ((value || helperText != "Press Enter to submit")) ? 1 : 0;});
},
child: TextField(
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
decoration: InputDecoration( decoration: InputDecoration(
hintText: defaultNickname, hintText: defaultNickname,
helper: Text("Press Enter to submit", style: TextStyle(color: Colors.grey, height: 0.2)), helper: AnimatedOpacity(
opacity: helperTextOpacity,
duration: Durations.long1,
curve: Easing.standardDecelerate,
child: Text(helperText, style: TextStyle(color: _defaultNicknameAnim.value, height: 0.2))
), ),
onChanged: (value) { ),
_setPlayer(value).then((v) {}); onSubmitted: (value) {
helperText = "Checking...";
_setDefaultNickname(value).then((v) {
_defaultNicknameAnim = v ? _goodDefaultNicknameAnim : _badDefaultNicknameAnim;
_defaultNicknameAnimController.forward(from: 0);
setState((){ helperText = v ? "Done!" : "Fuck";});
});
}, },
),
); );
}, },
)), )),
@ -415,7 +456,7 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
ListTile( ListTile(
title: Text("Show leaderboard based stats", style: Theme.of(context).textTheme.displayLarge), title: Text("Compare TL stats with rank averages", style: Theme.of(context).textTheme.displayLarge),
trailing: Switch(value: showAverages, onChanged: (bool value){ trailing: Switch(value: showAverages, onChanged: (bool value){
prefs.setBool("showAverages", value); prefs.setBool("showAverages", value);
setState(() { setState(() {
@ -426,7 +467,7 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
Divider(), Divider(),
Padding( Padding(
padding: descriptionPadding, padding: descriptionPadding,
child: Text("If on, Tetra Stats gonnna provide additional metrics, which will allow you to compare yourself with average player on your rank. The way you'll see it — stats will be highlited with corresponding color, hover over them with cursor for more info."), child: Text("If on, Tetra Stats will provide additional metrics, which allow you to compare yourself with average player on your rank. The way you'll see it — stats will be highlited with corresponding color, hover over them with cursor for more info."),
) )
], ],
), ),
@ -1474,7 +1515,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
final allPlayers = (snapshot.data != null) final allPlayers = (snapshot.data != null)
? snapshot.data as Map<String, String> ? snapshot.data as Map<String, String>
: <String, String>{}; : <String, String>{};
allPlayers.remove(prefs.getString("player") ?? "6098518e3d5155e6ec429cdc"); // player from the home button will be delisted allPlayers.remove(prefs.getString("playerID") ?? "6098518e3d5155e6ec429cdc"); // player from the home button will be delisted
List<String> keys = allPlayers.keys.toList(); List<String> keys = allPlayers.keys.toList();
return NestedScrollView( return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool value){ headerSliverBuilder: (BuildContext context, bool value){
@ -1502,7 +1543,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
child: ListTile( child: ListTile(
title: Text(prefs.getString("player") ?? "dan63"), title: Text(prefs.getString("player") ?? "dan63"),
onTap: () { onTap: () {
widget.changePlayer("6098518e3d5155e6ec429cdc"); widget.changePlayer(prefs.getString("playerID") ?? "6098518e3d5155e6ec429cdc");
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
), ),
@ -1533,8 +1574,9 @@ class TetraLeagueThingy extends StatelessWidget{
final TetraLeague league; final TetraLeague league;
final TetraLeague? toCompare; final TetraLeague? toCompare;
final Cutoffs? cutoffs; final Cutoffs? cutoffs;
final CutoffTetrio? averages;
const TetraLeagueThingy({super.key, required this.league, this.toCompare, this.cutoffs}); const TetraLeagueThingy({super.key, required this.league, this.toCompare, this.cutoffs, this.averages});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -1563,18 +1605,18 @@ class TetraLeagueThingy extends StatelessWidget{
defaultColumnWidth:const IntrinsicColumnWidth(), defaultColumnWidth:const IntrinsicColumnWidth(),
children: [ children: [
TableRow(children: [ TableRow(children: [
Text(f2.format(league.apm??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(f2.format(league.apm??0.00), textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: league.apm != null ? getStatColor(league.apm!, averages?.apm, true) : null)),
const Text(" APM", style: TextStyle(fontSize: 21)), Text(" APM", style: TextStyle(fontSize: 21, color: league.apm != null ? getStatColor(league.apm!, averages?.apm, true) : null)),
if (toCompare != null) Text(" (${comparef2.format(league.apm!-toCompare!.apm!)})", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: getDifferenceColor(league.apm!-toCompare!.apm!))) if (toCompare != null) Text(" (${comparef2.format(league.apm!-toCompare!.apm!)})", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: getDifferenceColor(league.apm!-toCompare!.apm!)))
]), ]),
TableRow(children: [ TableRow(children: [
Text(f2.format(league.pps??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(f2.format(league.pps??0.00), textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: league.pps != null ? getStatColor(league.pps!, averages?.pps, true) : null)),
const Text(" PPS", style: TextStyle(fontSize: 21)), Text(" PPS", style: TextStyle(fontSize: 21, color: league.pps != null ? getStatColor(league.pps!, averages?.pps, true) : null)),
if (toCompare != null) Text(" (${comparef2.format(league.pps!-toCompare!.pps!)})", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: getDifferenceColor(league.pps!-toCompare!.pps!))) if (toCompare != null) Text(" (${comparef2.format(league.pps!-toCompare!.pps!)})", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: getDifferenceColor(league.pps!-toCompare!.pps!)))
]), ]),
TableRow(children: [ TableRow(children: [
Text(f2.format(league.vs??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(f2.format(league.vs??0.00), textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: league.vs != null ? getStatColor(league.vs!, averages?.vs, true) : null)),
const Text(" VS", style: TextStyle(fontSize: 21)), Text(" VS", style: TextStyle(fontSize: 21, color: league.vs != null ? getStatColor(league.vs!, averages?.vs, true) : null)),
if (toCompare != null) Text(" (${comparef2.format(league.vs!-toCompare!.vs!)})", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: getDifferenceColor(league.vs!-toCompare!.vs!))) if (toCompare != null) Text(" (${comparef2.format(league.vs!-toCompare!.vs!)})", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: getDifferenceColor(league.vs!-toCompare!.vs!)))
]) ])
], ],
@ -1657,8 +1699,9 @@ class TetraLeagueThingy extends StatelessWidget{
class NerdStatsThingy extends StatelessWidget{ class NerdStatsThingy extends StatelessWidget{
final NerdStats nerdStats; final NerdStats nerdStats;
final NerdStats? oldNerdStats; final NerdStats? oldNerdStats;
final CutoffTetrio? averages;
const NerdStatsThingy({super.key, required this.nerdStats, this.oldNerdStats}); const NerdStatsThingy({super.key, required this.nerdStats, this.oldNerdStats, this.averages});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -1700,7 +1743,7 @@ class NerdStatsThingy extends StatelessWidget{
style: const TextStyle(fontFamily: "Eurostile Round"), style: const TextStyle(fontFamily: "Eurostile Round"),
children: [ children: [
const TextSpan(text: "APP\n"), const TextSpan(text: "APP\n"),
TextSpan(text: f3.format(nerdStats.app), style: const TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100)), TextSpan(text: f3.format(nerdStats.app), style: TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100, color: getStatColor(nerdStats.app, averages?.nerdStats?.app, true))),
if (oldNerdStats != null) TextSpan(text: "\n${comparef.format(nerdStats.app - oldNerdStats!.app)}", style: TextStyle(color: getDifferenceColor(nerdStats.app - oldNerdStats!.app))), if (oldNerdStats != null) TextSpan(text: "\n${comparef.format(nerdStats.app - oldNerdStats!.app)}", style: TextStyle(color: getDifferenceColor(nerdStats.app - oldNerdStats!.app))),
] ]
))), ))),
@ -1730,7 +1773,7 @@ class NerdStatsThingy extends StatelessWidget{
style: const TextStyle(fontFamily: "Eurostile Round"), style: const TextStyle(fontFamily: "Eurostile Round"),
children: [ children: [
const TextSpan(text: "VS/APM\n"), const TextSpan(text: "VS/APM\n"),
TextSpan(text: f3.format(nerdStats.vsapm), style: const TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100)), TextSpan(text: f3.format(nerdStats.vsapm), style: TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100, color: getStatColor(nerdStats.vsapm, averages?.nerdStats?.vsapm, true))),
if (oldNerdStats != null) TextSpan(text: "\n${comparef.format(nerdStats.vsapm - oldNerdStats!.vsapm)}", style: TextStyle(color: getDifferenceColor(nerdStats.vsapm - oldNerdStats!.vsapm))), if (oldNerdStats != null) TextSpan(text: "\n${comparef.format(nerdStats.vsapm - oldNerdStats!.vsapm)}", style: TextStyle(color: getDifferenceColor(nerdStats.vsapm - oldNerdStats!.vsapm))),
] ]
))), ))),
@ -1749,13 +1792,13 @@ class NerdStatsThingy extends StatelessWidget{
runSpacing: 10.0, runSpacing: 10.0,
runAlignment: WrapAlignment.start, runAlignment: WrapAlignment.start,
children: [ children: [
GaugetThingy(value: nerdStats.dss, oldValue: oldNerdStats?.dss, min: 0, max: 1.0, tickInterval: .2, label: "DS/S", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true), GaugetThingy(value: nerdStats.dss, oldValue: oldNerdStats?.dss, min: 0, max: 1.0, tickInterval: .2, label: "DS/S", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true, avgValue: averages?.nerdStats?.dss),
GaugetThingy(value: nerdStats.dsp, oldValue: oldNerdStats?.dsp, min: 0, max: 1.0, tickInterval: .2, label: "DS/P", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true), GaugetThingy(value: nerdStats.dsp, oldValue: oldNerdStats?.dsp, min: 0, max: 1.0, tickInterval: .2, label: "DS/P", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true, avgValue: averages?.nerdStats?.dsp),
GaugetThingy(value: nerdStats.appdsp, oldValue: oldNerdStats?.appdsp, min: 0, max: 1.2, tickInterval: .2, label: "APP+DS/P", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true), GaugetThingy(value: nerdStats.appdsp, oldValue: oldNerdStats?.appdsp, min: 0, max: 1.2, tickInterval: .2, label: "APP+DS/P", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true, avgValue: averages?.nerdStats?.appdsp),
GaugetThingy(value: nerdStats.cheese, oldValue: oldNerdStats?.cheese, min: -80, max: 80, tickInterval: 40, label: "Cheese", sideSize: 128.0, fractionDigits: 2, moreIsBetter: false), GaugetThingy(value: nerdStats.cheese, oldValue: oldNerdStats?.cheese, min: -80, max: 80, tickInterval: 40, label: "Cheese", sideSize: 128.0, fractionDigits: 2, moreIsBetter: false),
GaugetThingy(value: nerdStats.gbe, oldValue: oldNerdStats?.gbe, min: 0, max: 1.0, tickInterval: .2, label: "GbE", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true), GaugetThingy(value: nerdStats.gbe, oldValue: oldNerdStats?.gbe, min: 0, max: 1.0, tickInterval: .2, label: "GbE", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true, avgValue: averages?.nerdStats?.gbe),
GaugetThingy(value: nerdStats.nyaapp, oldValue: oldNerdStats?.nyaapp, min: 0, max: 1.2, tickInterval: .2, label: "wAPP", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true), GaugetThingy(value: nerdStats.nyaapp, oldValue: oldNerdStats?.nyaapp, min: 0, max: 1.2, tickInterval: .2, label: "wAPP", sideSize: 128.0, fractionDigits: 3, moreIsBetter: true, avgValue: averages?.nerdStats?.nyaapp),
GaugetThingy(value: nerdStats.area, oldValue: oldNerdStats?.area, min: 0, max: 1000, tickInterval: 100, label: "Area", sideSize: 128.0, fractionDigits: 1, moreIsBetter: true), GaugetThingy(value: nerdStats.area, oldValue: oldNerdStats?.area, min: 0, max: 1000, tickInterval: 100, label: "Area", sideSize: 128.0, fractionDigits: 1, moreIsBetter: true, avgValue: averages?.nerdStats?.area),
], ],
), ),
) )
@ -1807,13 +1850,14 @@ class GaugetThingy extends StatelessWidget{
final double min; final double min;
final double max; final double max;
final double? oldValue; final double? oldValue;
final double? avgValue;
final bool moreIsBetter; final bool moreIsBetter;
final double tickInterval; final double tickInterval;
final String label; final String label;
final double sideSize; final double sideSize;
final int fractionDigits; final int fractionDigits;
GaugetThingy({super.key, required this.value, required this.min, required this.max, this.oldValue, required this.tickInterval, required this.label, required this.sideSize, required this.fractionDigits, required this.moreIsBetter}); GaugetThingy({super.key, required this.value, required this.min, required this.max, this.oldValue, this.avgValue, required this.tickInterval, required this.label, required this.sideSize, required this.fractionDigits, required this.moreIsBetter});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -1839,7 +1883,7 @@ class GaugetThingy extends StatelessWidget{
], ],
annotations: [ annotations: [
GaugeAnnotation(widget: Container(child: GaugeAnnotation(widget: Container(child:
Text(f.format(value), textAlign: TextAlign.center, style: const TextStyle(fontSize: 25,fontWeight: FontWeight.bold))), Text(f.format(value), textAlign: TextAlign.center, style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold, color: getStatColor(value, avgValue, moreIsBetter)))),
angle: 90,positionFactor: 0.10 angle: 90,positionFactor: 0.10
), ),
GaugeAnnotation(widget: Container(child: GaugeAnnotation(widget: Container(child:

View File

@ -61,7 +61,7 @@ class UserState extends State<UserView> {
Card( Card(
child: Column( child: Column(
children: [ children: [
Text("Pornograph", style: TextStyle(),) Text("oskagalove", style: TextStyle(),)
] ]
), ),
), ),