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
artifacts: "build/windows/x64/runner/Release/TetraStats-${{github.ref_name}}-windows.zip"
tag: Auto-${{ github.run_number }}
body: Builded with GitHub Action workflow
body: Build with GitHub Action workflow
token: ${{ secrets.TOKEN }}
build-and-release-linux:
name: Build Linux App
@ -71,7 +71,7 @@ jobs:
discussionCategory: autobuilded-releases
artifacts: "build/linux/x64/release/bundle/TetraStats-${{github.ref_name}}-linux.zip"
tag: Auto-${{ github.run_number }}
body: Builded with GitHub Action workflow
body: Build with GitHub Action workflow
token: ${{ secrets.TOKEN }}
# build-and-release-android:
# name: Build Android App
@ -96,5 +96,5 @@ jobs:
# discussionCategory: autobuilded-releases
# artifacts: "build/app/outputs/flutter-apk/*"
# tag: Auto-${{ github.run_number }}
# body: Builded with GitHub Action workflow
# body: Build with GitHub Action workflow
# 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 {
late int pos;
@ -8,6 +8,7 @@ class CutoffTetrio {
late double? apm;
late double? pps;
late double? vs;
NerdStats? nerdStats;
late int count;
late double countPercentile;
@ -21,7 +22,9 @@ class CutoffTetrio {
required this.vs,
required this.count,
required this.countPercentile
});
}){
if (apm != null && pps != null && vs != null) nerdStats = NerdStats(apm!, pps!, vs!);
}
CutoffTetrio.fromJson(Map<String, dynamic> json, int total){
pos = json['pos'];
@ -33,6 +36,7 @@ class CutoffTetrio {
vs = json['vs']?.toDouble();
count = json['count'];
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;
}
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){
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_svg/flutter_svg.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/p1nkl0bst3r.dart';
import 'package:tetra_stats/data_objects/record_extras.dart';
@ -44,10 +45,11 @@ class FetchResults{
List<TetraLeague> states;
Summaries? summaries;
Cutoffs? cutoffs;
CutoffsTetrio? averages;
bool isTracked;
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{
@ -128,9 +130,10 @@ class RecordSummary extends StatelessWidget{
class LeagueCard extends StatelessWidget{
final TetraLeague league;
final CutoffTetrio? averages;
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
Widget build(BuildContext context) {
@ -157,7 +160,20 @@ class LeagueCard extends StatelessWidget{
const Divider(),
TLRatingThingy(userID: "", tlData: league, showPositions: true),
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? blitzBetterThanRankAverage;
Widget getOverviewCard(Summaries summaries){
Widget getOverviewCard(Summaries summaries, CutoffTetrio? averages){
return Column(
children: [
const Card(
@ -198,7 +214,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
),
),
),
LeagueCard(league: summaries.league),
LeagueCard(league: summaries.league, averages: averages),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
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;
return Column(
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(
//surfaceTintColor: rankColors[data.rank],
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!)
],
);
@ -1068,9 +1084,9 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
child: SlideTransition(
position: _offsetAnimation,
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){
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.records => getRecentTLrecords(widget.constraints),
_ => 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:tetra_stats/data_objects/badge.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/est_tr.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
}
}on TetrioPlayerNotExist{
return FetchResults(false, null, [], null, null, false, TetrioPlayerNotExist());
return FetchResults(false, null, [], null, null, null, false, TetrioPlayerNotExist());
}
late Summaries summaries;
late Cutoffs cutoffs;
List<dynamic> requests = await Future.wait([
teto.fetchSummaries(player.userId),
teto.fetchCutoffsBeanserver(),
]);
late CutoffsTetrio averages;
try {
List<dynamic> requests = await Future.wait([
teto.fetchSummaries(player.userId),
teto.fetchCutoffsBeanserver(),
teto.fetchCutoffsTetrio()
]);
summaries = requests[0];
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);
summaries = requests[0];
cutoffs = requests[1];
bool isTracking = await teto.isPlayerTracking(player.userId);
if (isTracking){ // if tracked - save data to local DB
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 {
@ -242,6 +251,7 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
SettingsCardMod mod = SettingsCardMod.general;
List<DropdownMenuItem<AppLocale>> locales = <DropdownMenuItem<AppLocale>>[];
String defaultNickname = "Checking...";
String defaultID = "";
late bool oskKagariGimmick;
late bool sheetbotRadarGraphs;
late int ratingMode;
@ -251,7 +261,11 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
late bool updateInBG;
final TextEditingController _playertext = TextEditingController();
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
void initState() {
@ -260,17 +274,30 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
// windowManager.setTitle("Tetra Stats: ${t.settings}");
// }
_defaultNicknameAnimController = AnimationController(
value: 1.0,
duration: Durations.extralong4,
vsync: this,
);
_defaultNicknameAnim = new Tween(
begin: 0.0,
end: 1.0,
_goodDefaultNicknameAnim = new ColorTween(
begin: Colors.greenAccent,
end: Colors.grey,
).animate(new CurvedAnimation(
parent: _defaultNicknameAnimController,
curve: Cubic(.15,-0.40,.86,-0.39),
reverseCurve: Cubic(0,.99,.99,1.01)
));
curve: Easing.emphasizedAccelerate,
//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();
super.initState();
}
@ -289,36 +316,35 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
sheetbotRadarGraphs = prefs.getBool("sheetbotRadarGraphs")?? false;
ratingMode = prefs.getInt("ratingMode") ?? 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 {
if (n != null) {
Future<bool> _setDefaultNickname(String n) async {
if (n.isNotEmpty) {
try {
defaultNickname = await teto.getNicknameByID(n);
if (n.length > 16){
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;
} on TetrioPlayerNotExist {
defaultNickname = n;
} catch (e) {
return false;
}
} else {
defaultNickname = "dan63047";
defaultNickname = "dan63";
await prefs.setString('player', "dan63");
await prefs.setString('playerID', "6098518e3d5155e6ec429cdc");
return true;
}
//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(){
return Column(
children: [
@ -341,15 +367,30 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
trailing: SizedBox(width: 150.0, child: AnimatedBuilder(
animation: _defaultNicknameAnim,
builder: (context, child) {
return TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: defaultNickname,
helper: Text("Press Enter to submit", style: TextStyle(color: Colors.grey, height: 0.2)),
),
onChanged: (value) {
_setPlayer(value).then((v) {});
return Focus(
onFocusChange: (value) {
setState((){helperTextOpacity = ((value || helperText != "Press Enter to submit")) ? 1 : 0;});
},
child: TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: defaultNickname,
helper: AnimatedOpacity(
opacity: helperTextOpacity,
duration: Durations.long1,
curve: Easing.standardDecelerate,
child: Text(helperText, style: TextStyle(color: _defaultNicknameAnim.value, height: 0.2))
),
),
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,
children: [
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){
prefs.setBool("showAverages", value);
setState(() {
@ -426,7 +467,7 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
Divider(),
Padding(
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)
? snapshot.data as Map<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();
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool value){
@ -1502,7 +1543,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
child: ListTile(
title: Text(prefs.getString("player") ?? "dan63"),
onTap: () {
widget.changePlayer("6098518e3d5155e6ec429cdc");
widget.changePlayer(prefs.getString("playerID") ?? "6098518e3d5155e6ec429cdc");
Navigator.of(context).pop();
},
),
@ -1533,8 +1574,9 @@ class TetraLeagueThingy extends StatelessWidget{
final TetraLeague league;
final TetraLeague? toCompare;
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
Widget build(BuildContext context) {
@ -1563,18 +1605,18 @@ class TetraLeagueThingy extends StatelessWidget{
defaultColumnWidth:const IntrinsicColumnWidth(),
children: [
TableRow(children: [
Text(f2.format(league.apm??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
const Text(" APM", style: 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)),
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!)))
]),
TableRow(children: [
Text(f2.format(league.pps??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
const Text(" PPS", style: 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)),
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!)))
]),
TableRow(children: [
Text(f2.format(league.vs??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
const Text(" VS", style: 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)),
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!)))
])
],
@ -1657,8 +1699,9 @@ class TetraLeagueThingy extends StatelessWidget{
class NerdStatsThingy extends StatelessWidget{
final NerdStats nerdStats;
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
Widget build(BuildContext context) {
@ -1700,7 +1743,7 @@ class NerdStatsThingy extends StatelessWidget{
style: const TextStyle(fontFamily: "Eurostile Round"),
children: [
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))),
]
))),
@ -1730,7 +1773,7 @@ class NerdStatsThingy extends StatelessWidget{
style: const TextStyle(fontFamily: "Eurostile Round"),
children: [
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))),
]
))),
@ -1749,13 +1792,13 @@ class NerdStatsThingy extends StatelessWidget{
runSpacing: 10.0,
runAlignment: WrapAlignment.start,
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.dsp, oldValue: oldNerdStats?.dsp, min: 0, max: 1.0, tickInterval: .2, label: "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),
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, 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, 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.gbe, oldValue: oldNerdStats?.gbe, min: 0, max: 1.0, tickInterval: .2, label: "GbE", 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),
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.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, 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, avgValue: averages?.nerdStats?.area),
],
),
)
@ -1807,13 +1850,14 @@ class GaugetThingy extends StatelessWidget{
final double min;
final double max;
final double? oldValue;
final double? avgValue;
final bool moreIsBetter;
final double tickInterval;
final String label;
final double sideSize;
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
Widget build(BuildContext context) {
@ -1839,7 +1883,7 @@ class GaugetThingy extends StatelessWidget{
],
annotations: [
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
),
GaugeAnnotation(widget: Container(child:

View File

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