HomeTab ready i guess

This commit is contained in:
dan63047 2024-08-16 00:55:45 +03:00
parent 6d950d30da
commit e323bf5898
5 changed files with 629 additions and 411 deletions

View File

@ -143,48 +143,6 @@ const Map<String, Color> rankColors = { // thanks osk for const rankColors at ht
'z': Color(0xFF375433) 'z': Color(0xFF375433)
}; };
// const Map<String, Duration> sprintAverages = { // old data, based on https://discord.com/channels/673303546107658242/917098364787650590/1214231970259673098
// 'x': Duration(seconds: 25, milliseconds: 413),
// 'u': Duration(seconds: 34, milliseconds: 549),
// 'ss': Duration(seconds: 43, milliseconds: 373),
// 's+': Duration(seconds: 54, milliseconds: 027),
// 's': Duration(seconds: 60, milliseconds: 412),
// 's-': Duration(seconds: 67, milliseconds: 381),
// 'a+': Duration(seconds: 73, milliseconds: 694),
// 'a': Duration(seconds: 81, milliseconds: 166),
// 'a-': Duration(seconds: 88, milliseconds: 334),
// 'b+': Duration(seconds: 93, milliseconds: 741),
// 'b': Duration(seconds: 98, milliseconds: 354),
// 'b-': Duration(seconds: 109, milliseconds: 610),
// 'c+': Duration(seconds: 124, milliseconds: 641),
// 'c': Duration(seconds: 126, milliseconds: 104),
// 'c-': Duration(seconds: 145, milliseconds: 865),
// 'd+': Duration(seconds: 154, milliseconds: 338),
// 'd': Duration(seconds: 162, milliseconds: 063),
// //'z': Duration(seconds: 66, milliseconds: 802)
// };
// const Map<String, int> blitzAverages = {
// 'x': 626494,
// 'u': 406059,
// 'ss': 243166,
// 's+': 168636,
// 's': 121594,
// 's-': 107845,
// 'a+': 87142,
// 'a': 73413,
// 'a-': 60799,
// 'b+': 55417,
// 'b': 47608,
// 'b-': 40534,
// 'c+': 34200,
// 'c': 32535,
// 'c-': 25808,
// 'd+': 23345,
// 'd': 23063,
// //'z': 72084
// };
const Map<String, Duration> sprintAverages = { // based on https://discord.com/channels/673303546107658242/674421736162197515/1244287342965952562 const Map<String, Duration> sprintAverages = { // based on https://discord.com/channels/673303546107658242/674421736162197515/1244287342965952562
'x': Duration(seconds: 25, milliseconds: 144), 'x': Duration(seconds: 25, milliseconds: 144),
'u': Duration(seconds: 36, milliseconds: 115), 'u': Duration(seconds: 36, milliseconds: 115),
@ -461,6 +419,7 @@ class Summaries{
RecordSingle? blitz; RecordSingle? blitz;
RecordSingle? zenith; RecordSingle? zenith;
RecordSingle? zenithEx; RecordSingle? zenithEx;
late List<Achievement> achievements;
late TetraLeagueAlpha league; late TetraLeagueAlpha league;
late TetrioZen zen; late TetrioZen zen;
@ -472,6 +431,7 @@ class Summaries{
if (json['blitz']['record'] != null) blitz = RecordSingle.fromJson(json['blitz']['record'], json['blitz']['rank'], json['40l']['rank_local']); if (json['blitz']['record'] != null) blitz = RecordSingle.fromJson(json['blitz']['record'], json['blitz']['rank'], json['40l']['rank_local']);
if (json['zenith']['record'] != null) zenith = RecordSingle.fromJson(json['zenith']['record'], json['zenith']['rank'], json['zenith']['rank_local']); if (json['zenith']['record'] != null) zenith = RecordSingle.fromJson(json['zenith']['record'], json['zenith']['rank'], json['zenith']['rank_local']);
if (json['zenithex']['record'] != null) zenithEx = RecordSingle.fromJson(json['zenithex']['record'], json['zenithex']['rank'], json['zenithex']['rank_local']); if (json['zenithex']['record'] != null) zenithEx = RecordSingle.fromJson(json['zenithex']['record'], json['zenithex']['rank'], json['zenithex']['rank_local']);
achievements = [for (var achievement in json['achievements']) Achievement.fromJson(achievement)];
league = TetraLeagueAlpha.fromJson(json['league'], DateTime.now()); league = TetraLeagueAlpha.fromJson(json['league'], DateTime.now());
zen = TetrioZen.fromJson(json['zen']); zen = TetrioZen.fromJson(json['zen']);
} }
@ -892,6 +852,104 @@ class EstTr {
} }
} }
class Achievement {
late int k;
int? o;
late int rt;
late int vt;
late int min;
late int deci;
late String name;
late String object;
late String category;
late bool hidden;
late int art;
late bool nolb;
late String desc;
late String n;
String? sId;
double? v;
late int? a;
DateTime? t;
int? pos;
int? total;
int? rank;
Achievement(
{required this.k,
this.o,
required this.rt,
required this.vt,
required this.min,
required this.deci,
required this.name,
required this.object,
required this.category,
required this.hidden,
required this.art,
required this.nolb,
required this.desc,
required this.n,
this.sId,
this.v,
required this.a,
this.t,
this.pos,
this.total,
this.rank});
Achievement.fromJson(Map<String, dynamic> json) {
k = json['k'];
o = json['o'];
rt = json['rt'];
vt = json['vt'];
min = json['min'];
deci = json['deci'];
name = json['name'];
object = json['object'];
category = json['category'];
hidden = json['hidden'];
art = json['art'];
nolb = json['nolb'];
desc = json['desc'];
n = json['n'];
sId = json['_id'];
v = json['v']?.toDouble();
a = json['a'];
t = json['t'] != null ? DateTime.parse(json['t']) : null;
pos = json['pos'];
total = json['total'];
rank = json['rank'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['k'] = k;
data['o'] = o;
data['rt'] = rt;
data['vt'] = vt;
data['min'] = min;
data['deci'] = deci;
data['name'] = name;
data['object'] = object;
data['category'] = category;
data['hidden'] = hidden;
data['art'] = art;
data['nolb'] = nolb;
data['desc'] = desc;
data['n'] = n;
data['_id'] = sId;
data['v'] = v;
data['a'] = a;
data['t'] = t.toString();
data['pos'] = pos;
data['total'] = total;
data['rank'] = rank;
return data;
}
}
class Playstyle { class Playstyle {
final double _apm; final double _apm;
final double _pps; final double _pps;

View File

@ -1140,6 +1140,8 @@ class TetrioService extends DB {
// more exceptions to god of exceptions // more exceptions to god of exceptions
case 403: case 403:
throw TetrioForbidden(); throw TetrioForbidden();
case 404:
throw TetrioPlayerNotExist();
case 429: case 429:
throw TetrioTooManyRequests(); throw TetrioTooManyRequests();
case 418: case 418:

View File

@ -51,63 +51,6 @@ Map<Cards, String> cardsTitles = {
//Cards.other: t.other //Cards.other: t.other
}; };
TetrioPlayer testPlayer = TetrioPlayer(
userId: "6098518e3d5155e6ec429cdc",
username: "dan63",
registrationTime: DateTime(2002, 2, 25, 9, 30, 01),
avatarRevision: 1704835194288,
bannerRevision: 1661462402700,
role: "user",
country: "BY",
state: DateTime(1970),
badges: [
Badge(badgeId: "kod_founder", label: "Убил оска", ts: DateTime(2023, 6, 27, 18, 51, 49)),
Badge(badgeId: "kod_by_founder", label: "Убит оском", ts: DateTime(2023, 6, 27, 18, 51, 51)),
Badge(badgeId: "5mblast_1", label: "5M Blast Winner"),
Badge(badgeId: "20tsd", label: "20 TSD"),
Badge(badgeId: "allclear", label: "10PC's"),
Badge(badgeId: "100player", label: "Won some shit"),
Badge(badgeId: "founder", label: "osk"),
Badge(badgeId: "early-supporter", label: "Sus"),
Badge(badgeId: "bugbounty", label: "Break some ribbons"),
Badge(badgeId: "infdev", label: "Closed player")
],
friendCount: 69,
gamesPlayed: 13747,
gamesWon: 6523,
gameTime: const Duration(days: 79, minutes: 28, seconds: 23, microseconds: 637591),
xp: 1415239,
supporterTier: 2,
verified: true,
connections: null,
tlSeason1: TetraLeagueAlpha(
timestamp: DateTime(1970),
gamesPlayed: 28,
gamesWon: 15,
bestRank: "x",
decaying: false,
rating: 23500.6194,
glicko: 3847.2134,
rd: 61.95383,
apm: 62.48,
pps: 1.85,
vs: 134.32,
rank: "x",
percentileRank: "x",
percentile: 0.00,
standing: 1,
standingLocal: 1,
nextAt: 1,
prevAt: 500
),
//distinguishment: Distinguishment(type: "twc", detail: "2023"),
bio: "кровбер не в палку, без последнего тспина - 32 атаки. кровбер не в палку, без первого тсм и последнего тспина - 30 атаки. кровбер в палку с б2б - 38 атаки.(5 б2б)(не знаю от чего зависит) кровбер в палку с б2б - 36 атаки.(5 б2б)(не знаю от чего зависит)"
);
News testNews = News("6098518e3d5155e6ec429cdc", [
NewsEntry(type: "personalbest", data: {"gametype": "40l", "result": 23.232}, timestamp: DateTime(2002, 2, 25, 10, 30, 01)),
NewsEntry(type: "personalbest", data: {"gametype": "blitz", "result": 23.232}, timestamp: DateTime(2002, 2, 25, 10, 30, 02)),
NewsEntry(type: "personalbest", data: {"gametype": "5mblast", "result": 23.232}, timestamp: DateTime(2002, 2, 25, 10, 30, 03)),
]);
late ScrollController controller; late ScrollController controller;
class _MainState extends State<MainView> with TickerProviderStateMixin { class _MainState extends State<MainView> with TickerProviderStateMixin {
@ -142,6 +85,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
body: LayoutBuilder( body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) { builder: (BuildContext context, BoxConstraints constraints) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
NavigationRail( NavigationRail(
leading: FloatingActionButton( leading: FloatingActionButton(
@ -201,12 +145,14 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
}); });
}, },
), ),
switch (destination){ Expanded(
0 => DestinationHome(searchFor: _searchFor, constraints: constraints), child: switch (destination){
1 => DestinationGraphs(searchFor: _searchFor, constraints: constraints), 0 => DestinationHome(searchFor: _searchFor, constraints: constraints),
2 => DestinationLeaderboards(constraints: constraints), 1 => DestinationGraphs(searchFor: _searchFor, constraints: constraints),
_ => Text("Unknown destination $destination") 2 => DestinationLeaderboards(constraints: constraints),
} _ => Text("Unknown destination $destination")
},
)
]); ]);
}, },
)); ));
@ -406,7 +352,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){ if (snapshot.hasData && snapshot.data!.isNotEmpty){
List<_HistoryChartSpot> selectedGraph = snapshot.data![_chartsIndex].value!; List<_HistoryChartSpot> selectedGraph = snapshot.data![_chartsIndex].value!;
yAxisTitle = _historyShortTitles[_chartsIndex]; yAxisTitle = _historyShortTitles[_chartsIndex];
return SingleChildScrollView( return SingleChildScrollView(
@ -531,12 +477,13 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
), ),
); );
} }
if (snapshot.hasError){ if (snapshot.hasError || snapshot.data!.isEmpty){
return Center(child: return Center(child:
Column( Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text(snapshot.error != null ? snapshot.error.toString() : "lol", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), Text(snapshot.error != null ? snapshot.error.toString() : t.noHistorySaved, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
Padding( Padding(
padding: const EdgeInsets.only(top: 8.0), padding: const EdgeInsets.only(top: 8.0),
child: Text(snapshot.stackTrace != null ? snapshot.stackTrace.toString() : "lol", textAlign: TextAlign.center), child: Text(snapshot.stackTrace != null ? snapshot.stackTrace.toString() : "lol", textAlign: TextAlign.center),
@ -576,8 +523,93 @@ class DestinationHome extends StatefulWidget{
State<DestinationHome> createState() => _DestinationHomeState(); State<DestinationHome> createState() => _DestinationHomeState();
} }
class FetchResults{
bool success;
TetrioPlayer? player;
Summaries? summaries;
Exception? exception;
FetchResults(this.success, this.player, this.summaries, this.exception);
}
class RecordSummary extends StatelessWidget{
final RecordSingle? record;
final bool hideRank;
final bool? betterThanRankAverage;
final MapEntry? closestAverage;
final bool? betterThanClosestAverage;
final String? rank;
const RecordSummary({super.key, required this.record, this.betterThanRankAverage, this.closestAverage, this.betterThanClosestAverage, this.rank, this.hideRank = false});
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
if (closestAverage != null && record != null) Padding(padding: const EdgeInsets.only(right: 8.0),
child: Image.asset("res/tetrio_tl_alpha_ranks/${closestAverage!.key}.png", height: 96))
else !hideRank ? Image.asset("res/tetrio_tl_alpha_ranks/z.png", height: 96) : Container(),
if (record != null) Column(
crossAxisAlignment: hideRank ? CrossAxisAlignment.center : CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
RichText(
textAlign: hideRank ? TextAlign.center : TextAlign.start,
text: TextSpan(
text: switch(record!.gamemode){
"40l" => get40lTime(record!.stats.finalTime.inMicroseconds),
"blitz" => NumberFormat.decimalPattern().format(record!.stats.score),
"5mblast" => get40lTime(record!.stats.finalTime.inMicroseconds),
"zenith" => "${f2.format(record!.stats.zenith!.altitude)} m",
"zenithex" => "${f2.format(record!.stats.zenith!.altitude)} m",
_ => record!.stats.score.toString()
},
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white, height: 0.9),
),
),
RichText(
textAlign: hideRank ? TextAlign.center : TextAlign.start,
text: TextSpan(
text: "",
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, color: Colors.grey),
children: [
if (rank != null && rank != "z") TextSpan(text: "${t.verdictGeneral(n: switch(record!.gamemode){
"40l" => readableTimeDifference(record!.stats.finalTime, sprintAverages[rank]!),
"blitz" => readableIntDifference(record!.stats.score, blitzAverages[rank]!),
_ => record!.stats.score.toString()
}, verdict: betterThanRankAverage??false ? t.verdictBetter : t.verdictWorse, rank: rank!.toUpperCase())}\n", style: TextStyle(
color: betterThanClosestAverage??false ? Colors.greenAccent : Colors.redAccent
))
else if ((rank == null || rank == "z") && closestAverage != null) TextSpan(text: "${t.verdictGeneral(n: switch(record!.gamemode){
"40l" => readableTimeDifference(record!.stats.finalTime, closestAverage!.value),
"blitz" => readableIntDifference(record!.stats.score, closestAverage!.value),
_ => record!.stats.score.toString()
}, verdict: betterThanClosestAverage??false ? t.verdictBetter : t.verdictWorse, rank: closestAverage!.key.toUpperCase())}\n", style: TextStyle(
color: betterThanClosestAverage??false ? Colors.greenAccent : Colors.redAccent
)),
if (record!.rank != -1) TextSpan(text: "${intf.format(record!.rank)}", style: TextStyle(color: getColorOfRank(record!.rank))),
if (record!.rank != -1 && record!.countryRank != -1) const TextSpan(text: ""),
if (record!.countryRank != -1) TextSpan(text: "${intf.format(record!.countryRank)} local", style: TextStyle(color: getColorOfRank(record!.countryRank))),
const TextSpan(text: "\n"),
TextSpan(text: timestamp(record!.timestamp)),
]
),
),
],
) else if (hideRank) RichText(text: TextSpan(
text: "---",
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.grey),
),
)
],
);
}
}
class _DestinationHomeState extends State<DestinationHome> { class _DestinationHomeState extends State<DestinationHome> {
Cards rightCard = Cards.tetraLeague; Cards rightCard = Cards.overview;
CardMod cardMod = CardMod.info; CardMod cardMod = CardMod.info;
Duration postSeasonLeft = seasonStart.difference(DateTime.now()); Duration postSeasonLeft = seasonStart.difference(DateTime.now());
late Map<Cards, List<ButtonSegment<CardMod>>> modeButtons; late Map<Cards, List<ButtonSegment<CardMod>>> modeButtons;
@ -588,8 +620,23 @@ class _DestinationHomeState extends State<DestinationHome> {
bool? sprintBetterThanRankAverage; bool? sprintBetterThanRankAverage;
bool? blitzBetterThanRankAverage; bool? blitzBetterThanRankAverage;
Future<FetchResults> _getData() async {
TetrioPlayer player;
try{
if (widget.searchFor.startsWith("ds:")){
player = await teto.fetchPlayer(widget.searchFor.substring(3), isItDiscordID: true); // we trying to get him with that
}else{
player = await teto.fetchPlayer(widget.searchFor); // Otherwise it's probably a user id or username
}
}on TetrioPlayerNotExist{
return FetchResults(false, null, null, TetrioPlayerNotExist());
}
Summaries summaries = await teto.fetchSummaries(player.userId);
return FetchResults(true, player, summaries, null);
}
Widget getOverviewCard(Summaries summaries){ Widget getOverviewCard(Summaries summaries){
return const Column( return Column(
children: [ children: [
Card( Card(
child: Padding( child: Padding(
@ -605,16 +652,181 @@ class _DestinationHomeState extends State<DestinationHome> {
), ),
), ),
), ),
Card(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("Tetra League", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
TLRatingThingy(userID: "", tlData: summaries.league)
],
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 8.0, 20.0, 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("40 Lines", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
RecordSummary(record: summaries.sprint, betterThanClosestAverage: sprintBetterThanClosestAverage, betterThanRankAverage: sprintBetterThanRankAverage, closestAverage: closestAverageSprint, rank: summaries.league.percentileRank),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
Text("Total runs submitted: ${summaries.achievements.firstWhere((e) => e.k == 5).v != null ? intf.format(summaries.achievements.firstWhere((e) => e.k == 5).v!) : "---"}", style: TextStyle(color: Colors.grey))
],
),
),
),
),
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 8.0, 20.0, 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("Blitz", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
RecordSummary(record: summaries.blitz, betterThanClosestAverage: blitzBetterThanClosestAverage, betterThanRankAverage: blitzBetterThanRankAverage, closestAverage: closestAverageBlitz, rank: summaries.league.percentileRank),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
Text("Total score gained: ${summaries.achievements.firstWhere((e) => e.k == 6).v != null ? intf.format(summaries.achievements.firstWhere((e) => e.k == 6).v!) : "---"}", style: TextStyle(color: Colors.grey))
],
),
),
),
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 8.0, 20.0, 14.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("QP", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
RecordSummary(record: summaries.zenith, hideRank: true),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
Text("Overall PB: ${summaries.achievements.firstWhere((e) => e.k == 18).v != null ? f2.format(summaries.achievements.firstWhere((e) => e.k == 18).v!) : "-.--"} m", style: TextStyle(color: Colors.grey))
],
),
),
),
),
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 8.0, 20.0, 14.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("QP Expert", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
RecordSummary(record: summaries.zenithEx, hideRank: true,),
const Divider(color: Color.fromARGB(50, 158, 158, 158)),
Text("Overall PB: ${summaries.achievements.firstWhere((e) => e.k == 19).v != null ? f2.format(summaries.achievements.firstWhere((e) => e.k == 19).v!) : "-.--"} m", style: TextStyle(color: Colors.grey))
],
),
),
),
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 8.0, 20.0, 14.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("Zen", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)),
Text("Level ${intf.format(summaries.zen.level)}", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white)),
Text("Score ${intf.format(summaries.zen.score)}"),
Text("Level up requirement: ${intf.format(summaries.zen.scoreRequirement)}", style: TextStyle(color: Colors.grey))
],
),
),
),
),
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
const Text("f", style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 65,
height: 1.2,
)),
const Positioned(left: 25, top: 20, child: Text("inesse", style: TextStyle(fontFamily: "Eurostile Round Extended"))),
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text("${(summaries.achievements.firstWhere((e) => e.k == 4).v != null && summaries.achievements.firstWhere((e) => e.k == 1).v != null) ?
f3.format(summaries.achievements.firstWhere((e) => e.k == 4).v!/summaries.achievements.firstWhere((e) => e.k == 1).v! * 100) : "--.---"}%", style: TextStyle(
//shadows: textShadow,
fontFamily: "Eurostile Round Extended",
fontSize: 36,
fontWeight: FontWeight.w500,
color: Colors.white
)),
)
],
),
Row(
children: [
Text("Total pieces placed:"),
Spacer(),
Text("${summaries.achievements.firstWhere((e) => e.k == 1).v != null ? intf.format(summaries.achievements.firstWhere((e) => e.k == 1).v!) : "---"}"),
],
),
Row(
children: [
Text(" - Placed with perfect finesse:"),
Spacer(),
Text("${summaries.achievements.firstWhere((e) => e.k == 4).v != null ? intf.format(summaries.achievements.firstWhere((e) => e.k == 4).v!) : "---"}"),
],
)
],
),
),
),
),
],
),
Card( Card(
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0), padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0),
child: Column( child: Column(
children: [ children: [
Row( if (summaries.achievements.firstWhere((e) => e.k == 16).v != null) Row(
children: [ children: [
Text("Title"), Text("Total height climbed in QP"),
Spacer(), Spacer(),
Text("Value"), Text("${f2.format(summaries.achievements.firstWhere((e) => e.k == 16).v!)} m"),
],
),
if (summaries.achievements.firstWhere((e) => e.k == 17).v != null) Row(
children: [
Text("KO's in QP"),
Spacer(),
Text("${intf.format(summaries.achievements.firstWhere((e) => e.k == 17).v!)}"),
], ],
) )
], ],
@ -643,8 +855,8 @@ class _DestinationHomeState extends State<DestinationHome> {
), ),
), ),
), ),
TetraLeagueThingy(league: testPlayer.tlSeason1!), TetraLeagueThingy(league: data),
Card( if (data.nerdStats != null) Card(
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -654,8 +866,8 @@ class _DestinationHomeState extends State<DestinationHome> {
], ],
), ),
), ),
NerdStatsThingy(nerdStats: testPlayer.tlSeason1!.nerdStats!), if (data.nerdStats != null) NerdStatsThingy(nerdStats: data.nerdStats!),
GraphsThingy(nerdStats: testPlayer.tlSeason1!.nerdStats!, playstyle: testPlayer.tlSeason1!.playstyle!, apm: testPlayer.tlSeason1!.apm!, pps: testPlayer.tlSeason1!.pps!, vs: testPlayer.tlSeason1!.vs!) if (data.nerdStats != null) GraphsThingy(nerdStats: data.nerdStats!, playstyle: data.playstyle!, apm: data.apm!, pps: data.pps!, vs: data.vs!)
], ],
); );
} }
@ -671,7 +883,7 @@ class _DestinationHomeState extends State<DestinationHome> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text(t.recent, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42)), Text(isTop ? t.top : t.recent, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42)),
], ],
), ),
), ),
@ -1153,27 +1365,53 @@ class _DestinationHomeState extends State<DestinationHome> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return FutureBuilder<FetchResults>(
children: [ future: _getData(),
SizedBox( builder: (context, snapshot) {
width: 450.0, switch (snapshot.connectionState){
child: FutureBuilder<TetrioPlayer>(future: teto.fetchPlayer(widget.searchFor), builder:(context, snapshot) { case ConnectionState.none:
switch (snapshot.connectionState){ case ConnectionState.waiting:
case ConnectionState.none: case ConnectionState.active:
case ConnectionState.waiting: return const Center(child: CircularProgressIndicator());
case ConnectionState.active: case ConnectionState.done:
return const Center(child: CircularProgressIndicator()); if (snapshot.hasError){
case ConnectionState.done: return Center(child:
if (snapshot.hasData){ Column(
return 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),
),
],
)
);
}
if (snapshot.hasData){
blitzBetterThanRankAverage = (snapshot.data!.summaries!.league.rank != "z" && snapshot.data!.summaries!.blitz != null) ? 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!.sprint!.stats.finalTime < sprintAverages[snapshot.data!.summaries!.league.rank]! : null;
if (snapshot.data!.summaries!.sprint != null) {
closestAverageSprint = sprintAverages.entries.singleWhere((element) => element.value == sprintAverages.values.reduce((a, b) => (a-snapshot.data!.summaries!.sprint!.stats.finalTime).abs() < (b -snapshot.data!.summaries!.sprint!.stats.finalTime).abs() ? a : b));
sprintBetterThanClosestAverage = snapshot.data!.summaries!.sprint!.stats.finalTime < closestAverageSprint!.value;
}
if (snapshot.data!.summaries!.blitz != null){
closestAverageBlitz = blitzAverages.entries.singleWhere((element) => element.value == blitzAverages.values.reduce((a, b) => (a-snapshot.data!.summaries!.blitz!.stats.score).abs() < (b -snapshot.data!.summaries!.blitz!.stats.score).abs() ? a : b));
blitzBetterThanClosestAverage = snapshot.data!.summaries!.blitz!.stats.score > closestAverageBlitz!.value;
}
return Row(
children: [
SizedBox(
width: 450,
child: Column(
children: [ children: [
NewUserThingy(player: snapshot.data!, showStateTimestamp: false, setState: setState), NewUserThingy(player: snapshot.data!.player!, showStateTimestamp: false, setState: setState),
if (snapshot.data!.badges.isNotEmpty) BadgesThingy(badges: snapshot.data!.badges), if (snapshot.data!.player!.badges.isNotEmpty) BadgesThingy(badges: snapshot.data!.player!.badges),
if (snapshot.data!.distinguishment != null) DistinguishmentThingy(snapshot.data!.distinguishment!), if (snapshot.data!.player!.distinguishment != null) DistinguishmentThingy(snapshot.data!.player!.distinguishment!),
if (snapshot.data!.role == "bot") FakeDistinguishmentThingy(bot: true, botMaintainers: snapshot.data!.botmaster), if (snapshot.data!.player!.role == "bot") FakeDistinguishmentThingy(bot: true, botMaintainers: snapshot.data!.player!.botmaster),
if (snapshot.data!.role == "banned") FakeDistinguishmentThingy(banned: true) if (snapshot.data!.player!.role == "banned") FakeDistinguishmentThingy(banned: true)
else if (snapshot.data!.badstanding == true) FakeDistinguishmentThingy(badStanding: true), else if (snapshot.data!.player!.badstanding == true) FakeDistinguishmentThingy(badStanding: true),
if (snapshot.data!.bio != null) Card( if (snapshot.data!.player!.bio != null) Card(
child: Column( child: Column(
children: [ children: [
Row( Row(
@ -1185,7 +1423,7 @@ class _DestinationHomeState extends State<DestinationHome> {
), ),
Padding( Padding(
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: MarkdownBody(data: snapshot.data!.bio!, styleSheet: MarkdownStyleSheet(textAlign: WrapAlignment.center)), child: MarkdownBody(data: snapshot.data!.player!.bio!, styleSheet: MarkdownStyleSheet(textAlign: WrapAlignment.center)),
) )
], ],
), ),
@ -1216,169 +1454,96 @@ class _DestinationHomeState extends State<DestinationHome> {
), ),
) )
], ],
); ),
}
if (snapshot.hasError){
if (snapshot.error.runtimeType == TetrioPlayerNotExist) {
return Card(
child: 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 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 Text("huh?");
}
},
)),
SizedBox(
width: widget.constraints.maxWidth - 450 - 80,
child: Column(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: widget.constraints.maxHeight - 64,
child: SingleChildScrollView(
child: FutureBuilder<Summaries>(
future: teto.fetchSummaries(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){
blitzBetterThanRankAverage = (snapshot.data!.league.rank != "z" && snapshot.data!.blitz != null) ? snapshot.data!.blitz!.stats.score > blitzAverages[snapshot.data!.league.rank]! : null;
sprintBetterThanRankAverage = (snapshot.data!.league.rank != "z" && snapshot.data!.sprint != null) ? snapshot.data!.sprint!.stats.finalTime < sprintAverages[snapshot.data!.league.rank]! : null;
if (snapshot.data!.sprint != null) {
closestAverageSprint = sprintAverages.entries.singleWhere((element) => element.value == sprintAverages.values.reduce((a, b) => (a-snapshot.data!.sprint!.stats.finalTime).abs() < (b -snapshot.data!.sprint!.stats.finalTime).abs() ? a : b));
sprintBetterThanClosestAverage = snapshot.data!.sprint!.stats.finalTime < closestAverageSprint!.value;
}
if (snapshot.data!.blitz != null){
closestAverageBlitz = blitzAverages.entries.singleWhere((element) => element.value == blitzAverages.values.reduce((a, b) => (a-snapshot.data!.blitz!.stats.score).abs() < (b -snapshot.data!.blitz!.stats.score).abs() ? a : b));
blitzBetterThanClosestAverage = snapshot.data!.blitz!.stats.score > closestAverageBlitz!.value;
}
return switch (rightCard){
Cards.overview => getOverviewCard(snapshot.data!),
Cards.tetraLeague => switch (cardMod){
CardMod.info => getTetraLeagueCard(snapshot.data!.league),
CardMod.recent => getRecentTLrecords(widget.constraints),
_ => Center(child: Text("huh?"))
},
Cards.quickPlay => switch (cardMod){
CardMod.info => getZenithCard(snapshot.data?.zenith),
CardMod.recent => getListOfRecords("zenith/recent", false, widget.constraints),
CardMod.top => getListOfRecords("zenith/top", true, widget.constraints),
CardMod.ex => getZenithCard(snapshot.data?.zenithEx),
CardMod.exRecent => getListOfRecords("zenithex/recent", false, widget.constraints),
CardMod.exTop => getListOfRecords("zenithex/top", true, widget.constraints),
_ => Center(child: Text("huh?"))
},
Cards.sprint => switch (cardMod){
CardMod.info => getRecordCard(snapshot.data?.sprint, sprintBetterThanRankAverage, closestAverageSprint, sprintBetterThanClosestAverage, snapshot.data!.league.rank),
CardMod.recent => getListOfRecords("40l/recent", false, widget.constraints),
CardMod.top => getListOfRecords("40l/top", true, widget.constraints),
_ => Center(child: Text("huh?"))
},
Cards.blitz => switch (cardMod){
CardMod.info => getRecordCard(snapshot.data?.blitz, blitzBetterThanRankAverage, closestAverageBlitz, blitzBetterThanClosestAverage, snapshot.data!.league.rank),
CardMod.recent => getListOfRecords("blitz/recent", false, widget.constraints),
CardMod.top => getListOfRecords("blitz/top", true, widget.constraints),
_ => Center(child: Text("huh?"))
},
};
}
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 const Text("lol");
}
}
),
), ),
), SizedBox(
if (modeButtons[rightCard]!.length > 1) SegmentedButton<CardMod>( width: widget.constraints.maxWidth - 450 - 80,
showSelectedIcon: false, child: Column(
selected: <CardMod>{cardMod}, children: [
segments: modeButtons[rightCard]!, SizedBox(
onSelectionChanged: (p0) { height: widget.constraints.maxHeight - 64,
setState(() { child: SingleChildScrollView(
cardMod = p0.first; child: switch (rightCard){
}); Cards.overview => getOverviewCard(snapshot.data!.summaries!),
}, Cards.tetraLeague => switch (cardMod){
), CardMod.info => getTetraLeagueCard(snapshot.data!.summaries!.league),
SegmentedButton<Cards>( CardMod.recent => getRecentTLrecords(widget.constraints),
showSelectedIcon: false, _ => Center(child: Text("huh?"))
segments: <ButtonSegment<Cards>>[ },
const ButtonSegment<Cards>( Cards.quickPlay => switch (cardMod){
value: Cards.overview, CardMod.info => getZenithCard(snapshot.data?.summaries!.zenith),
//label: Text('Overview'), CardMod.recent => getListOfRecords("zenith/recent", false, widget.constraints),
icon: Icon(Icons.calendar_view_day)), CardMod.top => getListOfRecords("zenith/top", true, widget.constraints),
ButtonSegment<Cards>( CardMod.ex => getZenithCard(snapshot.data?.summaries!.zenithEx),
value: Cards.tetraLeague, CardMod.exRecent => getListOfRecords("zenithex/recent", false, widget.constraints),
//label: Text('Tetra League'), CardMod.exTop => getListOfRecords("zenithex/top", true, widget.constraints),
icon: SvgPicture.asset("res/icons/league.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), _ => Center(child: Text("huh?"))
ButtonSegment<Cards>( },
value: Cards.quickPlay, Cards.sprint => switch (cardMod){
//label: Text('Quick Play'), CardMod.info => getRecordCard(snapshot.data?.summaries!.sprint, sprintBetterThanRankAverage, closestAverageSprint, sprintBetterThanClosestAverage, snapshot.data!.summaries!.league.rank),
icon: SvgPicture.asset("res/icons/qp.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), CardMod.recent => getListOfRecords("40l/recent", false, widget.constraints),
ButtonSegment<Cards>( CardMod.top => getListOfRecords("40l/top", true, widget.constraints),
value: Cards.sprint, _ => Center(child: Text("huh?"))
//label: Text('40 Lines'), },
icon: SvgPicture.asset("res/icons/40l.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), Cards.blitz => switch (cardMod){
ButtonSegment<Cards>( CardMod.info => getRecordCard(snapshot.data?.summaries!.blitz, blitzBetterThanRankAverage, closestAverageBlitz, blitzBetterThanClosestAverage, snapshot.data!.summaries!.league.rank),
value: Cards.blitz, CardMod.recent => getListOfRecords("blitz/recent", false, widget.constraints),
//label: Text('Blitz'), CardMod.top => getListOfRecords("blitz/top", true, widget.constraints),
icon: SvgPicture.asset("res/icons/blitz.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), _ => Center(child: Text("huh?"))
], },
selected: <Cards>{rightCard}, },
onSelectionChanged: (Set<Cards> newSelection) { ),
setState(() { ),
cardMod = CardMod.info; if (modeButtons[rightCard]!.length > 1) SegmentedButton<CardMod>(
rightCard = newSelection.first; showSelectedIcon: false,
});}) selected: <CardMod>{cardMod},
] segments: modeButtons[rightCard]!,
), onSelectionChanged: (p0) {
), setState(() {
// SizedBox( cardMod = p0.first;
// width: 450, });
// child: _TLRecords(userID: "snapshot.data![0].userId", changePlayer: changePlayer, data: [], wasActiveInTL: true, oldMathcesHere: false, separateScrollController: true) },
// ) ),
], SegmentedButton<Cards>(
); showSelectedIcon: false,
segments: <ButtonSegment<Cards>>[
const ButtonSegment<Cards>(
value: Cards.overview,
//label: Text('Overview'),
icon: Icon(Icons.calendar_view_day)),
ButtonSegment<Cards>(
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<Cards>(
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<Cards>(
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<Cards>(
value: Cards.blitz,
//label: Text('Blitz'),
icon: SvgPicture.asset("res/icons/blitz.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))),
],
selected: <Cards>{rightCard},
onSelectionChanged: (Set<Cards> newSelection) {
setState(() {
cardMod = CardMod.info;
rightCard = newSelection.first;
});})
],
)
)
],
);
}
}
return Text("End of FutureBuilder<FetchResults>");
},
);
} }
} }
@ -2145,18 +2310,15 @@ class TetraLeagueThingy extends StatelessWidget{
children: [ children: [
TableRow(children: [ TableRow(children: [
const Text("APM: ", style: TextStyle(fontSize: 21)), const Text("APM: ", style: TextStyle(fontSize: 21)),
Text(league.apm != null ? f2.format(league.apm) : "---", textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(f2.format(league.apm??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
//Text(" APM", style: TextStyle(fontSize: 21))
]), ]),
TableRow(children: [ TableRow(children: [
const Text("PPS: ", style: TextStyle(fontSize: 21)), const Text("PPS: ", style: TextStyle(fontSize: 21)),
Text(league.apm != null ? f2.format(league.pps) : "---", textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(f2.format(league.pps??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
//Text(" PPS", style: TextStyle(fontSize: 21))
]), ]),
TableRow(children: [ TableRow(children: [
const Text("VS: ", style: TextStyle(fontSize: 21)), const Text("VS: ", style: TextStyle(fontSize: 21)),
Text(league.apm != null ? f2.format(league.vs) : "---", textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(f2.format(league.vs??0.00), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
// Text(" VS", style: TextStyle(fontSize: 21))
]) ])
], ],
), ),
@ -2202,8 +2364,8 @@ class TetraLeagueThingy extends StatelessWidget{
children: [ children: [
TableRow(children: [ TableRow(children: [
//Text("VS: ", style: TextStyle(fontSize: 21)), //Text("VS: ", style: TextStyle(fontSize: 21)),
Text("${intf.format(league.standingLocal)}", textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text("${league.standingLocal.isNegative ? "---" : intf.format(league.standingLocal)}", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: league.standingLocal.isNegative ? Colors.grey : Colors.white)),
const Text(" in BY", style: TextStyle(fontSize: 21)) Text(" local", style: TextStyle(fontSize: 21, color: league.standingLocal.isNegative ? Colors.grey : Colors.white))
]), ]),
TableRow(children: [ TableRow(children: [
//Text("APM: ", style: TextStyle(fontSize: 21)), //Text("APM: ", style: TextStyle(fontSize: 21)),
@ -2237,94 +2399,99 @@ class NerdStatsThingy extends StatelessWidget{
return Card( return Card(
child: Column( child: Column(
children: [ children: [
Row( Padding(
mainAxisSize: MainAxisSize.min, padding: const EdgeInsets.fromLTRB(12.0, 0.0, 12.0, 0.0),
children: [ child: Row(
SizedBox( crossAxisAlignment: CrossAxisAlignment.center,
height: 256.0, mainAxisSize: MainAxisSize.min,
width: 256.0, children: [
child: ClipRRect( SizedBox(
borderRadius: BorderRadius.circular(1000), height: 256.0,
child: SfRadialGauge( width: 256.0,
backgroundColor: Colors.black, child: ClipRRect(
axes: [ borderRadius: BorderRadius.circular(1000),
RadialAxis( child: SfRadialGauge(
startAngle: 200, backgroundColor: Colors.black,
endAngle: 340, axes: [
minimum: 0.0, RadialAxis(
maximum: 1.0, startAngle: 200,
radiusFactor: 1.01, endAngle: 340,
showTicks: true, minimum: 0.0,
showLabels: false, maximum: 1.0,
interval: 0.1, radiusFactor: 1.01,
//labelsPosition: ElementsPosition.outside, showTicks: true,
ranges:[ showLabels: false,
GaugeRange(startValue: 0, endValue: nerdStats.app, color: theme.colorScheme.primary) interval: 0.1,
], //labelsPosition: ElementsPosition.outside,
annotations: [ ranges:[
GaugeAnnotation(widget: Container(child: GaugeRange(startValue: 0, endValue: nerdStats.app, color: theme.colorScheme.primary)
RichText( ],
textAlign: TextAlign.center, annotations: [
text: TextSpan( GaugeAnnotation(widget: Container(child:
style: const TextStyle(fontFamily: "Eurostile Round"), RichText(
children: [ textAlign: TextAlign.center,
const TextSpan(text: "APP\n"), text: TextSpan(
TextSpan(text: f3.format(nerdStats.app), style: const TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100)), style: const TextStyle(fontFamily: "Eurostile Round"),
//TextSpan(text: "\nAPP"), children: [
] const TextSpan(text: "APP\n"),
))), TextSpan(text: f3.format(nerdStats.app), style: const TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100)),
angle: 270,positionFactor: 0.5 //TextSpan(text: "\nAPP"),
), ]
], ))),
), angle: 270,positionFactor: 0.5
RadialAxis( ),
startAngle: 20, ],
endAngle: 160, ),
isInversed: true, RadialAxis(
minimum: 1.8, startAngle: 20,
maximum: 2.4, endAngle: 160,
radiusFactor: 1.01, isInversed: true,
showTicks: true, minimum: 1.8,
showLabels: false, maximum: 2.4,
interval: 0.1, radiusFactor: 1.01,
//labelsPosition: ElementsPosition.outside, showTicks: true,
ranges:[ showLabels: false,
GaugeRange(startValue: 0, endValue: nerdStats.vsapm, color: theme.colorScheme.primary) interval: 0.1,
], //labelsPosition: ElementsPosition.outside,
annotations: [ ranges:[
GaugeAnnotation(widget: Container(child: GaugeRange(startValue: 0, endValue: nerdStats.vsapm, color: theme.colorScheme.primary)
RichText( ],
textAlign: TextAlign.center, annotations: [
text: TextSpan( GaugeAnnotation(widget: Container(child:
style: const TextStyle(fontFamily: "Eurostile Round"), RichText(
children: [ textAlign: TextAlign.center,
const TextSpan(text: "VS/APM\n"), text: TextSpan(
TextSpan(text: f3.format(nerdStats.vsapm), style: const TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100)), style: const TextStyle(fontFamily: "Eurostile Round"),
] children: [
))), const TextSpan(text: "VS/APM\n"),
angle: 90,positionFactor: 0.5 TextSpan(text: f3.format(nerdStats.vsapm), style: const TextStyle(fontSize: 25, fontFamily: "Eurostile Round Extended", fontWeight: FontWeight.w100)),
) ]
], ))),
) angle: 90,positionFactor: 0.5
] )
],
)
]
),
), ),
), ),
), Expanded(
Expanded( child: Wrap(
child: Wrap( alignment: WrapAlignment.center,
spacing: 10, spacing: 10,
children: [ children: [
GaugetThingy(value: nerdStats.dss, min: 0, max: 1.0, tickInterval: .2, label: "DS/S", sideSize: 128.0, fractionDigits: 3), 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.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.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.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.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.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), GaugetThingy(value: nerdStats.area, min: 0, max: 1000, tickInterval: 100, label: "Area", sideSize: 128.0, fractionDigits: 1),
], ],
), ),
) )
] ]
),
), ),
], ],
) )

View File

@ -23,7 +23,7 @@ class TLRatingThingy extends StatelessWidget{
bool bigScreen = MediaQuery.of(context).size.width >= 768; bool bigScreen = MediaQuery.of(context).size.width >= 768;
String decimalSeparator = f4.symbols.DECIMAL_SEP; String decimalSeparator = f4.symbols.DECIMAL_SEP;
List<String> formatedTR = f4.format(tlData.rating).split(decimalSeparator); List<String> formatedTR = f4.format(tlData.rating).split(decimalSeparator);
List<String> formatedGlicko = f4.format(tlData.glicko).split(decimalSeparator); List<String> formatedGlicko = tlData.glicko != null ? f4.format(tlData.glicko).split(decimalSeparator) : ["---","--"];
List<String> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator); List<String> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator);
//DateTime now = DateTime.now(); //DateTime now = DateTime.now();
//bool beforeS1end = now.isBefore(seasonEnd); //bool beforeS1end = now.isBefore(seasonEnd);
@ -43,7 +43,7 @@ class TLRatingThingy extends StatelessWidget{
RichText( RichText(
text: TextSpan( text: TextSpan(
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 20, color: Colors.white), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 20, color: Colors.white),
children: switch(prefs.getInt("ratingMode")){ children: (tlData.gamesPlayed > 9) ? switch(prefs.getInt("ratingMode")){
1 => [ 1 => [
TextSpan(text: formatedGlicko[0], style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), TextSpan(text: formatedGlicko[0], style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
if (formatedGlicko.elementAtOrNull(1) != null) TextSpan(text: decimalSeparator + formatedGlicko[1]), if (formatedGlicko.elementAtOrNull(1) != null) TextSpan(text: decimalSeparator + formatedGlicko[1]),
@ -59,7 +59,7 @@ class TLRatingThingy extends StatelessWidget{
if (formatedTR.elementAtOrNull(1) != null) TextSpan(text: decimalSeparator + formatedTR[1]), if (formatedTR.elementAtOrNull(1) != null) TextSpan(text: decimalSeparator + formatedTR[1]),
TextSpan(text: " TR", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)) TextSpan(text: " TR", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28))
], ],
} } : [TextSpan(text: "---\n", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28, color: Colors.grey)), TextSpan(text: t.gamesUntilRanked(left: 10-tlData.gamesPlayed), style: TextStyle(color: Colors.grey, fontSize: 14)),]
) )
), ),
if (oldTl != null) Text( if (oldTl != null) Text(
@ -75,7 +75,7 @@ class TLRatingThingy extends StatelessWidget{
Colors.green Colors.green
), ),
), ),
Column( if (tlData.gamesPlayed > 9) Column(
children: [ children: [
RichText( RichText(
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -87,7 +87,7 @@ class TLRatingThingy extends StatelessWidget{
if (tlData.bestRank != "z") const TextSpan(text: ""), if (tlData.bestRank != "z") const TextSpan(text: ""),
if (tlData.bestRank != "z") TextSpan(text: "${t.topRank}: ${tlData.bestRank.toUpperCase()}"), if (tlData.bestRank != "z") TextSpan(text: "${t.topRank}: ${tlData.bestRank.toUpperCase()}"),
if (topTR != null) TextSpan(text: " (${f2.format(topTR)} TR)"), if (topTR != null) TextSpan(text: " (${f2.format(topTR)} TR)"),
TextSpan(text: "${prefs.getInt("ratingMode") == 1 ? "${f2.format(tlData.rating)} TR • RD: " : "Glicko: ${f2.format(tlData.glicko!)}±"}"), TextSpan(text: "${prefs.getInt("ratingMode") == 1 ? "${f2.format(tlData.rating)} TR • RD: " : "Glicko: ${tlData.glicko != null ? f2.format(tlData.glicko) : "---"}±"}"),
TextSpan(text: f2.format(tlData.rd!), style: tlData.decaying ? TextStyle(color: tlData.rd! > 98 ? Colors.red : Colors.yellow) : null), TextSpan(text: f2.format(tlData.rd!), style: tlData.decaying ? TextStyle(color: tlData.rd! > 98 ? Colors.red : Colors.yellow) : null),
if (tlData.decaying) WidgetSpan(child: Icon(Icons.trending_up, color: tlData.rd! > 98 ? Colors.red : Colors.yellow,), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic), if (tlData.decaying) WidgetSpan(child: Icon(Icons.trending_up, color: tlData.rd! > 98 ? Colors.red : Colors.yellow,), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic),
//if (beforeS1end) tlData.rd! <= safeRD ? TextSpan(text: " (Safe)", style: TextStyle(color: Colors.greenAccent)) : TextSpan(text: " (> ${safeRD} RD !!!)", style: TextStyle(color: Colors.redAccent)) //if (beforeS1end) tlData.rd! <= safeRD ? TextSpan(text: " (Safe)", style: TextStyle(color: Colors.greenAccent)) : TextSpan(text: " (> ${safeRD} RD !!!)", style: TextStyle(color: Colors.redAccent))

View File

@ -160,7 +160,7 @@ class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
}); });
}, },
), ),
if (currentTl.gamesPlayed > 9) TLRatingThingy(userID: widget.userID, tlData: currentTl, oldTl: oldTl, topTR: widget.topTR, lastMatchPlayed: widget.lastMatchPlayed), TLRatingThingy(userID: widget.userID, tlData: currentTl, oldTl: oldTl, topTR: widget.topTR, lastMatchPlayed: widget.lastMatchPlayed),
if (currentTl.gamesPlayed > 9) TLProgress( if (currentTl.gamesPlayed > 9) TLProgress(
tlData: currentTl, tlData: currentTl,
previousRankTRcutoff: widget.thatRankCutoff, previousRankTRcutoff: widget.thatRankCutoff,
@ -170,15 +170,6 @@ class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
nextRankGlickoCutoff: widget.nextRankCutoffGlicko, nextRankGlickoCutoff: widget.nextRankCutoffGlicko,
nextRankTRcutoffTarget: widget.nextRankTarget, nextRankTRcutoffTarget: widget.nextRankTarget,
), ),
if (currentTl.gamesPlayed < 10)
Text(t.gamesUntilRanked(left: 10 - currentTl.gamesPlayed),
softWrap: true,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "Eurostile Round",
fontSize: bigScreen ? 42 : 28,
overflow: TextOverflow.visible,
)),
Padding( Padding(
padding: const EdgeInsets.fromLTRB(8, 16, 8, 48), padding: const EdgeInsets.fromLTRB(8, 16, 8, 48),
child: Wrap( child: Wrap(