Zenith added
I probably should push Nerd Stats into new widget, but i planning to redo UI a little bit, so idk
This commit is contained in:
parent
90ad788c6c
commit
c1561fba80
|
@ -457,8 +457,10 @@ class TetrioPlayer {
|
||||||
|
|
||||||
class Summaries{
|
class Summaries{
|
||||||
late String id;
|
late String id;
|
||||||
late RecordSingle sprint;
|
RecordSingle? sprint;
|
||||||
late RecordSingle blitz;
|
RecordSingle? blitz;
|
||||||
|
RecordSingle? zenith;
|
||||||
|
RecordSingle? zenithEx;
|
||||||
late TetraLeagueAlpha league;
|
late TetraLeagueAlpha league;
|
||||||
late TetrioZen zen;
|
late TetrioZen zen;
|
||||||
|
|
||||||
|
@ -466,8 +468,10 @@ class Summaries{
|
||||||
|
|
||||||
Summaries.fromJson(Map<String, dynamic> json, String i){
|
Summaries.fromJson(Map<String, dynamic> json, String i){
|
||||||
id = i;
|
id = i;
|
||||||
sprint = RecordSingle.fromJson(json['40l']['record'], json['40l']['rank']);
|
if (json['40l']['record'] != null) sprint = RecordSingle.fromJson(json['40l']['record'], json['40l']['rank'], json['40l']['rank_local']);
|
||||||
blitz = RecordSingle.fromJson(json['blitz']['record'], json['blitz']['rank']);
|
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['zenithex']['record'] != null) zenithEx = RecordSingle.fromJson(json['zenithex']['record'], json['zenithex']['rank'], json['zenithex']['rank_local']);
|
||||||
league = TetraLeagueAlpha.fromJson(json['league'], DateTime.now());
|
league = TetraLeagueAlpha.fromJson(json['league'], DateTime.now());
|
||||||
zen = TetrioZen.fromJson(json['zen']);
|
zen = TetrioZen.fromJson(json['zen']);
|
||||||
}
|
}
|
||||||
|
@ -676,11 +680,13 @@ class ResultsStats {
|
||||||
late int piecesPlaced;
|
late int piecesPlaced;
|
||||||
late int lines;
|
late int lines;
|
||||||
late int score;
|
late int score;
|
||||||
late int seed;
|
int? seed;
|
||||||
late Duration finalTime;
|
late Duration finalTime;
|
||||||
late int tSpins;
|
late int tSpins;
|
||||||
late Clears clears;
|
late Clears clears;
|
||||||
late Finesse? finesse;
|
late int kills;
|
||||||
|
Finesse? finesse;
|
||||||
|
ZenithResults? zenith;
|
||||||
|
|
||||||
double get pps => piecesPlaced / (finalTime.inMicroseconds / 1000000);
|
double get pps => piecesPlaced / (finalTime.inMicroseconds / 1000000);
|
||||||
double get kpp => inputs / piecesPlaced;
|
double get kpp => inputs / piecesPlaced;
|
||||||
|
@ -717,7 +723,9 @@ class ResultsStats {
|
||||||
tSpins = json['tspins'];
|
tSpins = json['tspins'];
|
||||||
piecesPlaced = json['piecesplaced'];
|
piecesPlaced = json['piecesplaced'];
|
||||||
clears = Clears.fromJson(json['clears']);
|
clears = Clears.fromJson(json['clears']);
|
||||||
finesse = json.containsKey("finesse") ? Finesse.fromJson(json['finesse']) : null;
|
kills = json['kills'];
|
||||||
|
if (json.containsKey("finesse")) finesse = Finesse.fromJson(json['finesse']);
|
||||||
|
if (json.containsKey("zenith")) zenith = ZenithResults.fromJson(json['zenith']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
|
@ -739,6 +747,39 @@ class ResultsStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ZenithResults{
|
||||||
|
late double altitude;
|
||||||
|
late double rank;
|
||||||
|
late double peakrank;
|
||||||
|
late double avgrankpts;
|
||||||
|
late int floor;
|
||||||
|
late double targetingfactor;
|
||||||
|
late double targetinggrace;
|
||||||
|
late double totalbonus;
|
||||||
|
late int revives;
|
||||||
|
late int revivesTotal;
|
||||||
|
late bool speedrun;
|
||||||
|
late bool speedrunSeen;
|
||||||
|
late List<Duration> splits;
|
||||||
|
|
||||||
|
ZenithResults.fromJson(Map<String, dynamic> json){
|
||||||
|
altitude = json['altitude'].toDouble();
|
||||||
|
rank = json['rank'].toDouble();
|
||||||
|
peakrank = json['peakrank'].toDouble();
|
||||||
|
avgrankpts = json['avgrankpts'].toDouble();
|
||||||
|
floor = json['floor'];
|
||||||
|
targetingfactor = json['targetingfactor'].toDouble();
|
||||||
|
targetinggrace = json['targetinggrace'].toDouble();
|
||||||
|
totalbonus = json['totalbonus'].toDouble();
|
||||||
|
revives = json['revives'];
|
||||||
|
revivesTotal = json['revivesTotal'];
|
||||||
|
speedrun = json['speedrun'];
|
||||||
|
speedrunSeen = json['speedrun_seen'];
|
||||||
|
splits = [];
|
||||||
|
for (int ms in json['splits']) splits.add(Duration(milliseconds: ms));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Handling {
|
class Handling {
|
||||||
late num arr;
|
late num arr;
|
||||||
late num das;
|
late num das;
|
||||||
|
@ -997,7 +1038,7 @@ class SingleplayerStream{
|
||||||
userId = userID;
|
userId = userID;
|
||||||
type = tp;
|
type = tp;
|
||||||
records = [];
|
records = [];
|
||||||
for (var value in json) {records.add(RecordSingle.fromJson(value, null));}
|
for (var value in json) {records.add(RecordSingle.fromJson(value, -1, -1));}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,9 +1120,9 @@ class BetaLeagueStats{
|
||||||
}
|
}
|
||||||
|
|
||||||
BetaLeagueStats.fromJson(Map<String, dynamic> json){
|
BetaLeagueStats.fromJson(Map<String, dynamic> json){
|
||||||
apm = json['apm'].toDouble();
|
apm = json['apm'] != null ? json['apm'].toDouble() : 0.00;
|
||||||
pps = json['pps'].toDouble();
|
pps = json['apm'] != null ? json['pps'].toDouble() : 0.00;
|
||||||
vs = json['vsscore'].toDouble();
|
vs = json['apm'] != null ? json['vsscore'].toDouble() : 0.00;
|
||||||
garbageSent = json['garbagesent'];
|
garbageSent = json['garbagesent'];
|
||||||
garbageReceived = json['garbagereceived'];
|
garbageReceived = json['garbagereceived'];
|
||||||
kills = json['kills'];
|
kills = json['kills'];
|
||||||
|
@ -1364,11 +1405,13 @@ class RecordSingle {
|
||||||
late String gamemode;
|
late String gamemode;
|
||||||
late DateTime timestamp;
|
late DateTime timestamp;
|
||||||
late ResultsStats stats;
|
late ResultsStats stats;
|
||||||
int? rank;
|
late int rank;
|
||||||
|
late int countryRank;
|
||||||
|
late AggregateStats aggregateStats;
|
||||||
|
|
||||||
RecordSingle({required this.userId, required this.replayId, required this.ownId, required this.timestamp, required this.stats, this.rank});
|
RecordSingle({required this.userId, required this.replayId, required this.ownId, required this.timestamp, required this.stats, required this.rank, required this.countryRank, required this.aggregateStats});
|
||||||
|
|
||||||
RecordSingle.fromJson(Map<String, dynamic> json, int? ran) {
|
RecordSingle.fromJson(Map<String, dynamic> json, int ran, int cran) {
|
||||||
//developer.log("RecordSingle.fromJson: $json", name: "data_objects/tetrio");
|
//developer.log("RecordSingle.fromJson: $json", name: "data_objects/tetrio");
|
||||||
ownId = json['_id'];
|
ownId = json['_id'];
|
||||||
gamemode = json['gamemode'];
|
gamemode = json['gamemode'];
|
||||||
|
@ -1377,6 +1420,8 @@ class RecordSingle {
|
||||||
timestamp = DateTime.parse(json['ts']);
|
timestamp = DateTime.parse(json['ts']);
|
||||||
userId = json['user']['id'];
|
userId = json['user']['id'];
|
||||||
rank = ran;
|
rank = ran;
|
||||||
|
countryRank = cran;
|
||||||
|
aggregateStats = AggregateStats.fromJson(json['results']['aggregatestats']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
|
@ -1391,12 +1436,38 @@ class RecordSingle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AggregateStats{
|
||||||
|
late double apm;
|
||||||
|
late double pps;
|
||||||
|
late double vs;
|
||||||
|
late NerdStats nerdStats;
|
||||||
|
late EstTr estTr;
|
||||||
|
late Playstyle playstyle;
|
||||||
|
|
||||||
|
AggregateStats(this.apm, this.pps, this.vs){
|
||||||
|
nerdStats = NerdStats(apm, pps, vs);
|
||||||
|
estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
||||||
|
playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank);
|
||||||
|
}
|
||||||
|
|
||||||
|
AggregateStats.fromJson(Map<String, dynamic> json){
|
||||||
|
apm = json['apm'] != null ? json['apm'].toDouble() : 0.00;
|
||||||
|
pps = json['apm'] != null ? json['pps'].toDouble() : 0.00;
|
||||||
|
vs = json['apm'] != null ? json['vsscore'].toDouble() : 0.00;
|
||||||
|
nerdStats = NerdStats(apm, pps, vs);
|
||||||
|
estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
||||||
|
playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TetrioZen {
|
class TetrioZen {
|
||||||
late int level;
|
late int level;
|
||||||
late int score;
|
late int score;
|
||||||
|
|
||||||
TetrioZen({required this.level, required this.score});
|
TetrioZen({required this.level, required this.score});
|
||||||
|
|
||||||
|
double get scoreRequirement => (10000 + 10000 * ((log(level + 1) / log(2)) - 1));
|
||||||
|
|
||||||
TetrioZen.fromJson(Map<String, dynamic> json) {
|
TetrioZen.fromJson(Map<String, dynamic> json) {
|
||||||
level = json['level'];
|
level = json['level'];
|
||||||
score = json['score'];
|
score = json['score'];
|
||||||
|
|
|
@ -904,10 +904,10 @@ class TetrioService extends DB {
|
||||||
if (jsonDecode(response.body)['success']) {
|
if (jsonDecode(response.body)['success']) {
|
||||||
Map jsonRecords = jsonDecode(response.body);
|
Map jsonRecords = jsonDecode(response.body);
|
||||||
var sprint = jsonRecords['data']['records']['40l']['record'] != null
|
var sprint = jsonRecords['data']['records']['40l']['record'] != null
|
||||||
? RecordSingle.fromJson(jsonRecords['data']['records']['40l']['record'], jsonRecords['data']['records']['40l']['rank'])
|
? RecordSingle.fromJson(jsonRecords['data']['records']['40l']['record'], jsonRecords['data']['records']['40l']['rank'], jsonRecords['data']['records']['40l']['rank_local'])
|
||||||
: null;
|
: null;
|
||||||
var blitz = jsonRecords['data']['records']['blitz']['record'] != null
|
var blitz = jsonRecords['data']['records']['blitz']['record'] != null
|
||||||
? RecordSingle.fromJson(jsonRecords['data']['records']['blitz']['record'], jsonRecords['data']['records']['blitz']['rank'])
|
? RecordSingle.fromJson(jsonRecords['data']['records']['blitz']['record'], jsonRecords['data']['records']['blitz']['rank'], jsonRecords['data']['records']['blitz']['rank_local'])
|
||||||
: null;
|
: null;
|
||||||
var zen = TetrioZen.fromJson(jsonRecords['data']['zen']);
|
var zen = TetrioZen.fromJson(jsonRecords['data']['zen']);
|
||||||
UserRecords result = UserRecords(userID, sprint, blitz, zen);
|
UserRecords result = UserRecords(userID, sprint, blitz, zen);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||||
|
|
||||||
final NumberFormat secs = NumberFormat("00.###", LocaleSettings.currentLocale.languageCode);
|
final NumberFormat secs = NumberFormat("00.###", LocaleSettings.currentLocale.languageCode);
|
||||||
|
final NumberFormat fixedSecs = NumberFormat("00.000", LocaleSettings.currentLocale.languageCode);
|
||||||
final NumberFormat nonsecs = NumberFormat("00", LocaleSettings.currentLocale.languageCode);
|
final NumberFormat nonsecs = NumberFormat("00", LocaleSettings.currentLocale.languageCode);
|
||||||
final NumberFormat nonsecs3 = NumberFormat("000", LocaleSettings.currentLocale.languageCode);
|
final NumberFormat nonsecs3 = NumberFormat("000", LocaleSettings.currentLocale.languageCode);
|
||||||
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
||||||
|
@ -70,6 +71,10 @@ String get40lTime(int microseconds){
|
||||||
return microseconds > 60000000 ? "${(microseconds/1000000/60).floor()}:${(secs.format(microseconds /1000000 % 60))}" : _timeInSec.format(microseconds / 1000000);
|
return microseconds > 60000000 ? "${(microseconds/1000000/60).floor()}:${(secs.format(microseconds /1000000 % 60))}" : _timeInSec.format(microseconds / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getMoreNormalTime(Duration time){
|
||||||
|
return "${nonsecs.format(time.inMinutes)}:${(fixedSecs.format(time.inMilliseconds/1000%60))}";
|
||||||
|
}
|
||||||
|
|
||||||
/// Readable [a] - [b], without sign
|
/// Readable [a] - [b], without sign
|
||||||
String readableTimeDifference(Duration a, Duration b){
|
String readableTimeDifference(Duration a, Duration b){
|
||||||
Duration result = a - b;
|
Duration result = a - b;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import 'package:intl/intl.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
|
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetra_stats.dart';
|
import 'package:tetra_stats/data_objects/tetra_stats.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
import 'package:tetra_stats/gen/strings.g.dart';
|
import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
|
@ -23,6 +24,8 @@ import 'package:tetra_stats/utils/text_shadow.dart';
|
||||||
import 'package:tetra_stats/views/singleplayer_record_view.dart';
|
import 'package:tetra_stats/views/singleplayer_record_view.dart';
|
||||||
import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView;
|
import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView;
|
||||||
import 'package:tetra_stats/widgets/finesse_thingy.dart';
|
import 'package:tetra_stats/widgets/finesse_thingy.dart';
|
||||||
|
import 'package:tetra_stats/widgets/gauget_num.dart';
|
||||||
|
import 'package:tetra_stats/widgets/graphs.dart';
|
||||||
import 'package:tetra_stats/widgets/lineclears_thingy.dart';
|
import 'package:tetra_stats/widgets/lineclears_thingy.dart';
|
||||||
import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart';
|
import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart';
|
||||||
import 'package:tetra_stats/widgets/recent_sp_games.dart';
|
import 'package:tetra_stats/widgets/recent_sp_games.dart';
|
||||||
|
@ -430,12 +433,14 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
tabs: bigScreen ? [
|
tabs: bigScreen ? [
|
||||||
Tab(text: t.tetraLeague,),
|
Tab(text: t.tetraLeague,),
|
||||||
Tab(text: t.history),
|
Tab(text: t.history),
|
||||||
|
Tab(text: "Quick Play"),
|
||||||
Tab(text: "${t.sprint} & ${t.blitz}"),
|
Tab(text: "${t.sprint} & ${t.blitz}"),
|
||||||
Tab(text: t.other),
|
Tab(text: t.other),
|
||||||
] : [
|
] : [
|
||||||
Tab(text: t.tetraLeague),
|
Tab(text: t.tetraLeague),
|
||||||
Tab(text: t.tlRecords),
|
Tab(text: t.tlRecords),
|
||||||
Tab(text: t.history),
|
Tab(text: t.history),
|
||||||
|
Tab(text: "Quick Play"),
|
||||||
Tab(text: t.sprint),
|
Tab(text: t.sprint),
|
||||||
Tab(text: t.blitz),
|
Tab(text: t.blitz),
|
||||||
Tab(text: t.recentRuns),
|
Tab(text: t.recentRuns),
|
||||||
|
@ -478,6 +483,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
),
|
),
|
||||||
],),
|
],),
|
||||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![1].league.gamesPlayed > 0),
|
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![1].league.gamesPlayed > 0),
|
||||||
|
_ZenithThingy(record: snapshot.data![1].zenith, recordEX: snapshot.data![1].zenithEx),
|
||||||
_TwoRecordsThingy(sprint: snapshot.data![1].sprint, blitz: snapshot.data![1].blitz, rank: snapshot.data![1].league.percentileRank, recent: SingleplayerStream(userId: "userId", records: [], type: "recent"), sprintStream: SingleplayerStream(userId: "userId", records: [], type: "40l"), blitzStream: SingleplayerStream(userId: "userId", records: [], type: "blitz")),
|
_TwoRecordsThingy(sprint: snapshot.data![1].sprint, blitz: snapshot.data![1].blitz, rank: snapshot.data![1].league.percentileRank, recent: SingleplayerStream(userId: "userId", records: [], type: "recent"), sprintStream: SingleplayerStream(userId: "userId", records: [], type: "40l"), blitzStream: SingleplayerStream(userId: "userId", records: [], type: "blitz")),
|
||||||
_OtherThingy(zen: snapshot.data![1].zen, bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![2])
|
_OtherThingy(zen: snapshot.data![1].zen, bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![2])
|
||||||
] : [
|
] : [
|
||||||
|
@ -500,6 +506,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
),
|
),
|
||||||
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3].records, wasActiveInTL: true, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true),
|
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3].records, wasActiveInTL: true, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true),
|
||||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![1].league.gamesPlayed > 0),
|
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![1].league.gamesPlayed > 0),
|
||||||
|
_ZenithThingy(record: snapshot.data![1].zenith, recordEX: snapshot.data![1].zenithEx),
|
||||||
SingleplayerRecord(record: snapshot.data![1].sprint, rank: snapshot.data![1].league.percentileRank, stream: SingleplayerStream(userId: "userId", records: [], type: "40l")),
|
SingleplayerRecord(record: snapshot.data![1].sprint, rank: snapshot.data![1].league.percentileRank, stream: SingleplayerStream(userId: "userId", records: [], type: "40l")),
|
||||||
SingleplayerRecord(record: snapshot.data![1].blitz, rank: snapshot.data![1].league.percentileRank, stream: SingleplayerStream(userId: "userId", records: [], type: "Blitz")),
|
SingleplayerRecord(record: snapshot.data![1].blitz, rank: snapshot.data![1].league.percentileRank, stream: SingleplayerStream(userId: "userId", records: [], type: "Blitz")),
|
||||||
_RecentSingleplayersThingy(SingleplayerStream(userId: "userId", records: [], type: "recent")),
|
_RecentSingleplayersThingy(SingleplayerStream(userId: "userId", records: [], type: "recent")),
|
||||||
|
@ -1218,7 +1225,230 @@ class _RecentSingleplayersThingy extends StatelessWidget {
|
||||||
child: RecentSingleplayerGames(recent: recent, hideTitle: true)
|
child: RecentSingleplayerGames(recent: recent, hideTitle: true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ZenithThingy extends StatefulWidget{
|
||||||
|
final RecordSingle? record;
|
||||||
|
final RecordSingle? recordEX;
|
||||||
|
|
||||||
|
_ZenithThingy({this.record, this.recordEX});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_ZenithThingy> createState() => _ZenithThingyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ZenithThingyState extends State<_ZenithThingy> {
|
||||||
|
late RecordSingle? record;
|
||||||
|
bool ex = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState(){
|
||||||
|
super.initState();
|
||||||
|
record = ex ? widget.recordEX : widget.record;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return LayoutBuilder(builder: (context, constraints){
|
||||||
|
bool bigScreen = constraints.maxWidth > 768;
|
||||||
|
if (record == null) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text("Quick Play${ex ? " Expert" : ""}", style: const TextStyle(height: 0.1, fontFamily: "Eurostile Round Extended", fontSize: 18)),
|
||||||
|
RichText(text: TextSpan(
|
||||||
|
text: "--- m",
|
||||||
|
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 36 : 32, fontWeight: FontWeight.w500, color: Colors.grey),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(onPressed: (){
|
||||||
|
if (ex){
|
||||||
|
ex = false;
|
||||||
|
}else{
|
||||||
|
ex = true;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
record = ex ? widget.recordEX : widget.record;
|
||||||
|
});
|
||||||
|
}, child: Text(ex ? "Switch to normal" : "Switch to Expert")),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Padding(padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text("Quick Play${ex ? " Expert" : ""}", style: const TextStyle(height: 0.1, fontFamily: "Eurostile Round Extended", fontSize: 18)),
|
||||||
|
RichText(text: TextSpan(
|
||||||
|
text: "${f2.format(record!.stats.zenith!.altitude)} m",
|
||||||
|
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 36 : 32, fontWeight: FontWeight.w500, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
text: "",
|
||||||
|
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, color: Colors.grey),
|
||||||
|
children: [
|
||||||
|
if (record!.rank != -1) TextSpan(text: "№${record!.rank}"),
|
||||||
|
if (record!.rank != -1) const TextSpan(text: " • "),
|
||||||
|
if (record!.countryRank != -1) TextSpan(text: "№${record!.countryRank} local"),
|
||||||
|
if (record!.countryRank != -1) const TextSpan(text: " • "),
|
||||||
|
TextSpan(text: timestamp(widget.record!.timestamp)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(onPressed: (){
|
||||||
|
if (ex){
|
||||||
|
ex = false;
|
||||||
|
}else{
|
||||||
|
ex = true;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
record = ex ? widget.recordEX : widget.record;
|
||||||
|
});
|
||||||
|
}, child: Text(ex ? "Switch to normal" : "Switch to Expert")),
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
|
spacing: 20,
|
||||||
|
children: [
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.apm, playerStatLabel: t.statCellNum.apm, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: true),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: false),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.vs, playerStatLabel: t.statCellNum.vs, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: true),
|
||||||
|
StatCellNum(playerStat: record!.stats.kills, playerStatLabel: "Kills", isScreenBig: bigScreen, higherIsBetter: true)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
FinesseThingy(record?.stats.finesse, record?.stats.finessePercentage),
|
||||||
|
LineclearsThingy(record!.stats.clears, record!.stats.lines, record!.stats.holds, record!.stats.tSpins),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 300,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text("Total time: ${getMoreNormalTime(record!.stats.finalTime)}", style: const TextStyle(color: Colors.white, fontFamily: "Eurostile Round Extended"), textAlign: TextAlign.center),
|
||||||
|
Table(
|
||||||
|
children: [
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
Text("Floor"),
|
||||||
|
Text("Split"),
|
||||||
|
Text("Total"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
for (int i = 0; i < record!.stats.zenith!.splits.length; i++) TableRow(
|
||||||
|
children: [
|
||||||
|
Text((i+1).toString()),
|
||||||
|
Text(record!.stats.zenith!.splits[i] != Duration.zero ? getMoreNormalTime(record!.stats.zenith!.splits[i]-(i-1 != -1 ? record!.stats.zenith!.splits[i-1] : Duration.zero)) : "--:--.---"),
|
||||||
|
Text(record!.stats.zenith!.splits[i] != Duration.zero ? getMoreNormalTime(record!.stats.zenith!.splits[i]) : "--:--.---"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text(t.nerdStats, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 40, 0, 0),
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 35,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
children: [
|
||||||
|
GaugetNum(playerStat: record!.aggregateStats.nerdStats.app, playerStatLabel: t.statCellNum.app, higherIsBetter: true, minimum: 0, maximum: 1, ranges: [
|
||||||
|
GaugeRange(startValue: 0, endValue: 0.2, color: Colors.red),
|
||||||
|
GaugeRange(startValue: 0.2, endValue: 0.4, color: Colors.yellow),
|
||||||
|
GaugeRange(startValue: 0.4, endValue: 0.6, color: Colors.green),
|
||||||
|
GaugeRange(startValue: 0.6, endValue: 0.8, color: Colors.blue),
|
||||||
|
GaugeRange(startValue: 0.8, endValue: 1, color: Colors.purple),
|
||||||
|
], alertWidgets: [
|
||||||
|
Text(t.statCellNum.appDescription),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.app}")
|
||||||
|
]),
|
||||||
|
GaugetNum(playerStat: record!.aggregateStats.nerdStats.vsapm, playerStatLabel: "VS / APM", higherIsBetter: true, minimum: 1.8, maximum: 2.4, ranges: [
|
||||||
|
GaugeRange(startValue: 1.8, endValue: 2.0, color: Colors.green),
|
||||||
|
GaugeRange(startValue: 2.0, endValue: 2.2, color: Colors.blue),
|
||||||
|
GaugeRange(startValue: 2.2, endValue: 2.4, color: Colors.purple),
|
||||||
|
], alertWidgets: [
|
||||||
|
Text(t.statCellNum.vsapmDescription),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.vsapm}")
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 25,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
children: [
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.dss, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.dss,
|
||||||
|
alertWidgets: [Text(t.statCellNum.dssDescription),
|
||||||
|
Text("${t.formula}: (VS / 100) - (APM / 60)"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.dss}"),],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: true,),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.dsp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.dsp,
|
||||||
|
alertWidgets: [Text(t.statCellNum.dspDescription),
|
||||||
|
Text("${t.formula}: DS/S / PPS"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.dsp}"),],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: true),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.appdsp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.appdsp,
|
||||||
|
alertWidgets: [Text(t.statCellNum.appdspDescription),
|
||||||
|
Text("${t.formula}: APP + DS/P"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.appdsp}"),],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: true),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.cheese, isScreenBig: bigScreen, fractionDigits: 2, playerStatLabel: t.statCellNum.cheese,
|
||||||
|
alertWidgets: [Text(t.statCellNum.cheeseDescription),
|
||||||
|
Text("${t.formula}: (DS/P * 150) + ((VS/APM - 2) * 50) + (0.6 - APP) * 125"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.cheese}"),],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: false),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.gbe, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.gbe,
|
||||||
|
alertWidgets: [Text(t.statCellNum.gbeDescription),
|
||||||
|
Text("${t.formula}: APP * DS/P * 2"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.gbe}"),],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: true),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.nyaapp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.nyaapp,
|
||||||
|
alertWidgets: [Text(t.statCellNum.nyaappDescription),
|
||||||
|
Text("${t.formula}: APP - 5 * tan(radians((Cheese Index / -30) + 1))"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.nyaapp}")],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: true),
|
||||||
|
StatCellNum(playerStat: record!.aggregateStats.nerdStats.area, isScreenBig: bigScreen, fractionDigits: 1, playerStatLabel: t.statCellNum.area,
|
||||||
|
alertWidgets: [Text(t.statCellNum.areaDescription),
|
||||||
|
Text("${t.formula}: APM * 1 + PPS * 45 + VS * 0.444 + APP * 185 + DS/S * 175 + DS/P * 450 + Garbage Effi * 315"),
|
||||||
|
Text("${t.exactValue}: ${record!.aggregateStats.nerdStats.area}"),],
|
||||||
|
okText: t.popupActions.ok,
|
||||||
|
higherIsBetter: true)
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 16.0),
|
||||||
|
child: Graphs(record!.aggregateStats.apm, record!.aggregateStats.pps, record!.aggregateStats.vs, record!.aggregateStats.nerdStats, record!.aggregateStats.playstyle),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _OtherThingy extends StatelessWidget {
|
class _OtherThingy extends StatelessWidget {
|
||||||
|
@ -1314,6 +1544,7 @@ class _OtherThingy extends StatelessWidget {
|
||||||
"40l" => get40lTime((news.data["result"]*1000).floor()),
|
"40l" => get40lTime((news.data["result"]*1000).floor()),
|
||||||
"5mblast" => get40lTime((news.data["result"]*1000).floor()),
|
"5mblast" => get40lTime((news.data["result"]*1000).floor()),
|
||||||
"zenith" => "${f2.format(news.data["result"])} m.",
|
"zenith" => "${f2.format(news.data["result"])} m.",
|
||||||
|
"zenithex" => "${f2.format(news.data["result"])} m.",
|
||||||
_ => "unknown"
|
_ => "unknown"
|
||||||
},
|
},
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold)
|
style: const TextStyle(fontWeight: FontWeight.bold)
|
||||||
|
@ -1463,6 +1694,14 @@ class _OtherThingy extends StatelessWidget {
|
||||||
Text(t.zen, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
Text(t.zen, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||||
Text("${t.statCellNum.level} ${NumberFormat.decimalPattern().format(zen!.level)}", style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold)),
|
Text("${t.statCellNum.level} ${NumberFormat.decimalPattern().format(zen!.level)}", style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold)),
|
||||||
Text("${t.statCellNum.score} ${NumberFormat.decimalPattern().format(zen!.score)}", style: const TextStyle(fontSize: 18)),
|
Text("${t.statCellNum.score} ${NumberFormat.decimalPattern().format(zen!.score)}", style: const TextStyle(fontSize: 18)),
|
||||||
|
Container(
|
||||||
|
constraints: BoxConstraints(maxWidth: 300.0),
|
||||||
|
child: Row(children: [
|
||||||
|
Text("Score requirement to level up:"),
|
||||||
|
Spacer(),
|
||||||
|
Text(intf.format(zen!.scoreRequirement))
|
||||||
|
],),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -68,8 +68,21 @@ News testNews = News("6098518e3d5155e6ec429cdc", [
|
||||||
NewsEntry(type: "personalbest", data: {"gametype": "blitz", "result": 23.232}, timestamp: DateTime(2002, 2, 25, 10, 30, 02)),
|
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)),
|
NewsEntry(type: "personalbest", data: {"gametype": "5mblast", "result": 23.232}, timestamp: DateTime(2002, 2, 25, 10, 30, 03)),
|
||||||
]);
|
]);
|
||||||
|
late ScrollController controller;
|
||||||
|
|
||||||
class _MainState extends State<MainView> with TickerProviderStateMixin {
|
class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
controller = ScrollController();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(body: Row(
|
return Scaffold(body: Row(
|
||||||
|
@ -94,6 +107,16 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
],
|
],
|
||||||
selectedIndex: 0
|
selectedIndex: 0
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Scrollbar(
|
||||||
|
controller: controller,
|
||||||
|
thumbVisibility: true,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
controller: controller,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 450.0,
|
width: 450.0,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -225,8 +248,45 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 450.0,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Spacer(),
|
||||||
|
Text("test card"),
|
||||||
|
Spacer()
|
||||||
|
],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 450.0,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Spacer(),
|
||||||
|
Text("test card"),
|
||||||
|
Spacer()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ class StatCellNum extends StatelessWidget {
|
||||||
required this.playerStat,
|
required this.playerStat,
|
||||||
required this.playerStatLabel,
|
required this.playerStatLabel,
|
||||||
required this.isScreenBig,
|
required this.isScreenBig,
|
||||||
this.smallDecimal = true,
|
this.smallDecimal = false,
|
||||||
this.alertWidgets,
|
this.alertWidgets,
|
||||||
this.fractionDigits,
|
this.fractionDigits,
|
||||||
this.oldPlayerStat,
|
this.oldPlayerStat,
|
||||||
|
|
Loading…
Reference in New Issue