From 49c5dfdf5a33df2f122df916e41050a8bc3646a7 Mon Sep 17 00:00:00 2001 From: dan63047 Date: Sun, 3 Mar 2024 01:26:31 +0300 Subject: [PATCH] Experimental changes for tl_match_view --- lib/views/calc_view.dart | 133 +-- lib/views/compare_view.dart | 889 +++++++++--------- lib/views/main_view.dart | 21 +- lib/views/tl_match_view.dart | 1022 +++++++++++++-------- lib/widgets/list_tile_trailing_stats.dart | 33 + 5 files changed, 1179 insertions(+), 919 deletions(-) create mode 100644 lib/widgets/list_tile_trailing_stats.dart diff --git a/lib/views/calc_view.dart b/lib/views/calc_view.dart index 0828a73..d942746 100644 --- a/lib/views/calc_view.dart +++ b/lib/views/calc_view.dart @@ -68,72 +68,77 @@ class CalcState extends State { ), backgroundColor: Colors.black, body: SafeArea( - child: NestedScrollView( - controller: _scrollController, - headerSliverBuilder: (context, value) { - return [ - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.fromLTRB(14, 16, 16, 32), - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(right: 12), - child: TextField( - onSubmitted: (value) => calc(), - controller: apmController, - keyboardType: TextInputType.number, - decoration: const InputDecoration(label: Text("APM"), alignLabelWithHint: true), - ), - )), - Expanded( - child: TextField( - onSubmitted: (value) => calc(), - controller: ppsController, - keyboardType: TextInputType.number, - decoration: const InputDecoration(label: Text("PPS"), alignLabelWithHint: true), - )), - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 12), - child: TextField( - onSubmitted: (value) => calc(), - controller: vsController, - keyboardType: TextInputType.number, - decoration: const InputDecoration(label: Text("VS"), alignLabelWithHint: true), - ), - )), - TextButton( - onPressed: () => calc(), - child: Text(t.calc), + child: Center( + child: Container( + constraints: BoxConstraints(maxWidth: 768), + child: NestedScrollView( + controller: _scrollController, + headerSliverBuilder: (context, value) { + return [ + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.fromLTRB(14, 16, 16, 32), + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(right: 12), + child: TextField( + onSubmitted: (value) => calc(), + controller: apmController, + keyboardType: TextInputType.number, + decoration: const InputDecoration(label: Text("APM"), alignLabelWithHint: true), + ), + )), + Expanded( + child: TextField( + onSubmitted: (value) => calc(), + controller: ppsController, + keyboardType: TextInputType.number, + decoration: const InputDecoration(label: Text("PPS"), alignLabelWithHint: true), + )), + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 12), + child: TextField( + onSubmitted: (value) => calc(), + controller: vsController, + keyboardType: TextInputType.number, + decoration: const InputDecoration(label: Text("VS"), alignLabelWithHint: true), + ), + )), + TextButton( + onPressed: () => calc(), + child: Text(t.calc), + ), + ], ), - ], + ), ), - ), - ), - const SliverToBoxAdapter( - child: Divider(), - ) - ]; - }, - body: nerdStats == null - ? Text(t.calcViewNoValues) - : ListView( - children: [ - _ListEntry(value: nerdStats!.app, label: t.statCellNum.app.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: nerdStats!.vsapm, label: "VS/APM", fractionDigits: 3), - _ListEntry(value: nerdStats!.dss, label: t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: nerdStats!.dsp, label: t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: nerdStats!.appdsp, label: "APP + DS/P", fractionDigits: 3), - _ListEntry(value: nerdStats!.cheese, label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: nerdStats!.gbe, label: t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: nerdStats!.nyaapp, label: t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: nerdStats!.area, label: t.statCellNum.area.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), - _ListEntry(value: estTr!.esttr, label: t.statCellNum.estOfTR, fractionDigits: 3), - Graphs(apm!, pps!, vs!, nerdStats!, playstyle!), - ], - )), + const SliverToBoxAdapter( + child: Divider(), + ) + ]; + }, + body: nerdStats == null + ? Text(t.calcViewNoValues) + : ListView( + children: [ + _ListEntry(value: nerdStats!.app, label: t.statCellNum.app.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: nerdStats!.vsapm, label: "VS/APM", fractionDigits: 3), + _ListEntry(value: nerdStats!.dss, label: t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: nerdStats!.dsp, label: t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: nerdStats!.appdsp, label: "APP + DS/P", fractionDigits: 3), + _ListEntry(value: nerdStats!.cheese, label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: nerdStats!.gbe, label: t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: nerdStats!.nyaapp, label: t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: nerdStats!.area, label: t.statCellNum.area.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3), + _ListEntry(value: estTr!.esttr, label: t.statCellNum.estOfTR, fractionDigits: 3), + Graphs(apm!, pps!, vs!, nerdStats!, playstyle!), + ], + )), + ), + ), ), ); } diff --git a/lib/views/compare_view.dart b/lib/views/compare_view.dart index 2dd567f..c3755fb 100644 --- a/lib/views/compare_view.dart +++ b/lib/views/compare_view.dart @@ -256,443 +256,453 @@ class CompareState extends State { appBar: AppBar(title: Text("$titleGreenSide ${t.vs} $titleRedSide")), backgroundColor: Colors.black, body: SafeArea( - child: NestedScrollView( - controller: _scrollController, - headerSliverBuilder: (context, value) { - return [ - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.fromLTRB(16, 16, 16, 32), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [Colors.green, Colors.transparent], - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - stops: [0.0, 0.4], - )), - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), - child: PlayerSelector( - data: theGreenSide, - mode: greenSideMode, - fetch: fetchGreenSide, - change: changeGreenSide, - updateState: _justUpdate, + child: Center( + child: Container( + constraints: BoxConstraints(maxWidth: 768), + child: NestedScrollView( + controller: _scrollController, + headerSliverBuilder: (context, value) { + return [ + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 32), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.green, Colors.transparent], + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + stops: [0.0, 0.4], + )), + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), + child: PlayerSelector( + data: theGreenSide, + mode: greenSideMode, + fetch: fetchGreenSide, + change: changeGreenSide, + updateState: _justUpdate, + ), + ), ), ), - ), - ), - const Padding( - padding: EdgeInsets.only(top: 16), - child: Text("VS"), - ), - Expanded( - child: Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [Colors.red, Colors.transparent], - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - stops: [0.0, 0.4], - )), - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), - child: PlayerSelector( - data: theRedSide, - mode: redSideMode, - fetch: fetchRedSide, - change: changeRedSide, - updateState: _justUpdate, + const Padding( + padding: EdgeInsets.only(top: 16), + child: Text("VS"), + ), + Expanded( + child: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.red, Colors.transparent], + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + stops: [0.0, 0.4], + )), + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), + child: PlayerSelector( + data: theRedSide, + mode: redSideMode, + fetch: fetchRedSide, + change: changeRedSide, + updateState: _justUpdate, + ), + ), ), ), - ), + ], ), - ], + ), ), + const SliverToBoxAdapter( + child: Divider(), + ) + ]; + }, + body: Center( + child: Container( + constraints: BoxConstraints(maxWidth: 768), + child: ListView( + children: !listEquals(theGreenSide, [null, null, null]) && !listEquals(theRedSide, [null, null, null])? [ + if (theGreenSide[0] != null && + theRedSide[0] != null && + theGreenSide[0]!.role != "banned" && + theRedSide[0]!.role != "banned") + Column( + children: [ + CompareRegTimeThingy( + greenSide: theGreenSide[0].registrationTime, + redSide: theRedSide[0].registrationTime, + label: t.registred), + CompareThingy( + label: t.statCellNum.level, + greenSide: theGreenSide[0].level, + redSide: theRedSide[0].level, + higherIsBetter: true, + fractionDigits: 2, + ), + if (!theGreenSide[0].gameTime.isNegative && + !theRedSide[0].gameTime.isNegative) + CompareThingy( + greenSide: theGreenSide[0].gameTime.inMicroseconds / + 1000000 / + 60 / + 60, + redSide: theRedSide[0].gameTime.inMicroseconds / + 1000000 / + 60 / + 60, + label: t.statCellNum.hoursPlayed.replaceAll(RegExp(r'\n'), " "), + higherIsBetter: true, + fractionDigits: 2, + ), + if (theGreenSide[0].gamesPlayed >= 0 && + theRedSide[0].gamesPlayed >= 0) + CompareThingy( + label: t.statCellNum.onlineGames.replaceAll(RegExp(r'\n'), " "), + greenSide: theGreenSide[0].gamesPlayed, + redSide: theRedSide[0].gamesPlayed, + higherIsBetter: true, + ), + if (theGreenSide[0].gamesWon >= 0 && + theRedSide[0].gamesWon >= 0) + CompareThingy( + label: t.statCellNum.gamesWon.replaceAll(RegExp(r'\n'), " "), + greenSide: theGreenSide[0].gamesWon, + redSide: theRedSide[0].gamesWon, + higherIsBetter: true, + ), + CompareThingy( + label: t.statCellNum.friends, + greenSide: theGreenSide[0].friendCount, + redSide: theRedSide[0].friendCount, + higherIsBetter: true, + ), + const Divider(), + ], + ), + if (theGreenSide[0] != null && + theRedSide[0] != null && + (theGreenSide[0]!.role == "banned" || + theRedSide[0]!.role == "banned")) + CompareBoolThingy( + greenSide: theGreenSide[0].role == "banned", + redSide: theRedSide[0].role == "banned", + label: t.normalBanned, + trueIsBetter: false), + (theGreenSide[2].gamesPlayed > 0 || greenSideMode == Mode.stats) && + (theRedSide[2].gamesPlayed > 0 || redSideMode == Mode.stats) + ? Column( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(t.tetraLeague, + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: bigScreen ? 42 : 28)), + ), + if (theGreenSide[2].gamesPlayed > 9 && + theRedSide[2].gamesPlayed > 9 && + greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: "TR", + greenSide: theGreenSide[2].rating, + redSide: theRedSide[2].rating, + fractionDigits: 2, + higherIsBetter: true, + ), + if (greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), + greenSide: theGreenSide[2].gamesPlayed, + redSide: theRedSide[2].gamesPlayed, + higherIsBetter: true, + ), + if (greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: t.statCellNum.gamesWonTL.replaceAll(RegExp(r'\n'), " "), + greenSide: theGreenSide[2].gamesWon, + redSide: theRedSide[2].gamesWon, + higherIsBetter: true, + ), + if (greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: "WR %", + greenSide: + theGreenSide[2].winrate * 100, + redSide: theRedSide[2].winrate * 100, + fractionDigits: 2, + higherIsBetter: true, + ), + if (theGreenSide[2].gamesPlayed > 9 && + theRedSide[2].gamesPlayed > 9 && + greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: "Glicko", + greenSide: theGreenSide[2].glicko!, + redSide: theRedSide[2].glicko!, + fractionDigits: 2, + higherIsBetter: true, + ), + if (theGreenSide[2].gamesPlayed > 9 && + theRedSide[2].gamesPlayed > 9 && + greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: "RD", + greenSide: theGreenSide[2].rd!, + redSide: theRedSide[2].rd!, + fractionDigits: 3, + higherIsBetter: false, + ), + if (theGreenSide[2].standing > 0 && + theRedSide[2].standing > 0 && + greenSideMode == Mode.player && + redSideMode == Mode.player) + CompareThingy( + label: t.statCellNum.lbpShort, + greenSide: theGreenSide[2].standing, + redSide: theRedSide[2].standing, + higherIsBetter: false, + ), + if (theGreenSide[2].standingLocal > 0 && + theRedSide[2].standingLocal > 0 && + greenSideMode == Mode.player && + redSideMode == Mode.player) + CompareThingy( + label: t.statCellNum.lbpcShort, + greenSide: + theGreenSide[2].standingLocal, + redSide: theRedSide[2].standingLocal, + higherIsBetter: false, + ), + if (theGreenSide[2].apm != null && + theRedSide[2].apm != null) + CompareThingy( + label: "APM", + greenSide: theGreenSide[2].apm!, + redSide: theRedSide[2].apm!, + fractionDigits: 2, + higherIsBetter: true, + ), + if (theGreenSide[2].pps != null && + theRedSide[2].pps != null) + CompareThingy( + label: "PPS", + greenSide: theGreenSide[2].pps!, + redSide: theRedSide[2].pps!, + fractionDigits: 2, + higherIsBetter: true, + ), + if (theGreenSide[2].vs != null && + theRedSide[2].vs != null) + CompareThingy( + label: "VS", + greenSide: theGreenSide[2].vs!, + redSide: theRedSide[2].vs!, + fractionDigits: 2, + higherIsBetter: true, + ), + ], + ) + : CompareBoolThingy( + greenSide: theGreenSide[2].gamesPlayed > 0, + redSide: theRedSide[2].gamesPlayed > 0, + label: t.playedTL, + trueIsBetter: false), + const Divider(), + if (theGreenSide[2].nerdStats != null && + theRedSide[2].nerdStats != null) + Column( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(t.nerdStats, + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: bigScreen ? 42 : 28)), + ), + CompareThingy( + label: "APP", + greenSide: theGreenSide[2].nerdStats!.app, + redSide: theRedSide[2].nerdStats!.app, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "VS/APM", + greenSide: theGreenSide[2].nerdStats!.vsapm, + redSide: theRedSide[2].nerdStats!.vsapm, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "DS/S", + greenSide: theGreenSide[2].nerdStats!.dss, + redSide: theRedSide[2].nerdStats!.dss, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "DS/P", + greenSide: theGreenSide[2].nerdStats!.dsp, + redSide: theRedSide[2].nerdStats!.dsp, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "APP + DS/P", + greenSide: + theGreenSide[2].nerdStats!.appdsp, + redSide: theRedSide[2].nerdStats!.appdsp, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), + greenSide: + theGreenSide[2].nerdStats!.cheese, + redSide: theRedSide[2].nerdStats!.cheese, + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: "Gb Eff.", + greenSide: theGreenSide[2].nerdStats!.gbe, + redSide: theRedSide[2].nerdStats!.gbe, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "wAPP", + greenSide: + theGreenSide[2].nerdStats!.nyaapp, + redSide: theRedSide[2].nerdStats!.nyaapp, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Area", + greenSide: theGreenSide[2].nerdStats!.area, + redSide: theRedSide[2].nerdStats!.area, + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: t.statCellNum.estOfTRShort, + greenSide: theGreenSide[2].estTr!.esttr, + redSide: theRedSide[2].estTr!.esttr, + fractionDigits: 2, + higherIsBetter: true, + ), + if (theGreenSide[2].gamesPlayed > 9 && + theGreenSide[2].gamesPlayed > 9 && + greenSideMode != Mode.stats && + redSideMode != Mode.stats) + CompareThingy( + label: t.statCellNum.accOfEstShort, + greenSide: theGreenSide[2].esttracc!, + redSide: theRedSide[2].esttracc!, + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: "Opener", + greenSide: theGreenSide[2].playstyle!.opener, + redSide: theRedSide[2].playstyle!.opener, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Plonk", + greenSide: theGreenSide[2].playstyle!.plonk, + redSide: theRedSide[2].playstyle!.plonk, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Stride", + greenSide: theGreenSide[2].playstyle!.stride, + redSide: theRedSide[2].playstyle!.stride, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Inf. DS", + greenSide: theGreenSide[2].playstyle!.infds, + redSide: theRedSide[2].playstyle!.infds, + fractionDigits: 3, + higherIsBetter: true, + ), + VsGraphs(theGreenSide[2].apm!, theGreenSide[2].pps!, theGreenSide[2].vs!, theGreenSide[2].nerdStats!, theGreenSide[2].playstyle!, theRedSide[2].apm!, theRedSide[2].pps!, theRedSide[2].vs!, theRedSide[2].nerdStats!, theRedSide[2].playstyle!), + const Divider(), + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(t.winChance, + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: bigScreen ? 42 : 28)), + ), + if (greenSideMode != Mode.stats && redSideMode != Mode.stats && + theGreenSide[2].gamesPlayed > 9 && theRedSide[2].gamesPlayed > 9) + CompareThingy( + label: t.byGlicko, + greenSide: getWinrateByTR( + theGreenSide[2].glicko!, + theGreenSide[2].rd!, + theRedSide[2].glicko!, + theRedSide[2].rd!) * + 100, + redSide: getWinrateByTR( + theRedSide[2].glicko!, + theRedSide[2].rd!, + theGreenSide[2].glicko!, + theGreenSide[2].rd!) * + 100, + fractionDigits: 2, + higherIsBetter: true, + postfix: "%", + ), + CompareThingy( + label: t.byEstTR, + greenSide: getWinrateByTR( + theGreenSide[2].estTr!.estglicko, + theGreenSide[2].rd ?? noTrRd, + theRedSide[2].estTr!.estglicko, + theRedSide[2].rd ?? noTrRd) * + 100, + redSide: getWinrateByTR( + theRedSide[2].estTr!.estglicko, + theRedSide[2].rd ?? noTrRd, + theGreenSide[2].estTr!.estglicko, + theGreenSide[2].rd ?? noTrRd) * + 100, + fractionDigits: 2, + higherIsBetter: true, + postfix: "%", + ), + ], + ) + ] : [Padding( + padding: const EdgeInsets.all(8.0), + child: Text(t.compareViewNoValues(avgR: "\$avgR"), textAlign: TextAlign.center), + )], // This is so fucked up holy shit + ), ), - ), - const SliverToBoxAdapter( - child: Divider(), ) - ]; - }, - body: ListView( - children: !listEquals(theGreenSide, [null, null, null]) && !listEquals(theRedSide, [null, null, null])? [ - if (theGreenSide[0] != null && - theRedSide[0] != null && - theGreenSide[0]!.role != "banned" && - theRedSide[0]!.role != "banned") - Column( - children: [ - CompareRegTimeThingy( - greenSide: theGreenSide[0].registrationTime, - redSide: theRedSide[0].registrationTime, - label: t.registred), - CompareThingy( - label: t.statCellNum.level, - greenSide: theGreenSide[0].level, - redSide: theRedSide[0].level, - higherIsBetter: true, - fractionDigits: 2, - ), - if (!theGreenSide[0].gameTime.isNegative && - !theRedSide[0].gameTime.isNegative) - CompareThingy( - greenSide: theGreenSide[0].gameTime.inMicroseconds / - 1000000 / - 60 / - 60, - redSide: theRedSide[0].gameTime.inMicroseconds / - 1000000 / - 60 / - 60, - label: t.statCellNum.hoursPlayed.replaceAll(RegExp(r'\n'), " "), - higherIsBetter: true, - fractionDigits: 2, - ), - if (theGreenSide[0].gamesPlayed >= 0 && - theRedSide[0].gamesPlayed >= 0) - CompareThingy( - label: t.statCellNum.onlineGames.replaceAll(RegExp(r'\n'), " "), - greenSide: theGreenSide[0].gamesPlayed, - redSide: theRedSide[0].gamesPlayed, - higherIsBetter: true, - ), - if (theGreenSide[0].gamesWon >= 0 && - theRedSide[0].gamesWon >= 0) - CompareThingy( - label: t.statCellNum.gamesWon.replaceAll(RegExp(r'\n'), " "), - greenSide: theGreenSide[0].gamesWon, - redSide: theRedSide[0].gamesWon, - higherIsBetter: true, - ), - CompareThingy( - label: t.statCellNum.friends, - greenSide: theGreenSide[0].friendCount, - redSide: theRedSide[0].friendCount, - higherIsBetter: true, - ), - const Divider(), - ], - ), - if (theGreenSide[0] != null && - theRedSide[0] != null && - (theGreenSide[0]!.role == "banned" || - theRedSide[0]!.role == "banned")) - CompareBoolThingy( - greenSide: theGreenSide[0].role == "banned", - redSide: theRedSide[0].role == "banned", - label: t.normalBanned, - trueIsBetter: false), - (theGreenSide[2].gamesPlayed > 0 || greenSideMode == Mode.stats) && - (theRedSide[2].gamesPlayed > 0 || redSideMode == Mode.stats) - ? Column( - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(t.tetraLeague, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - ), - if (theGreenSide[2].gamesPlayed > 9 && - theRedSide[2].gamesPlayed > 9 && - greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: "TR", - greenSide: theGreenSide[2].rating, - redSide: theRedSide[2].rating, - fractionDigits: 2, - higherIsBetter: true, - ), - if (greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), - greenSide: theGreenSide[2].gamesPlayed, - redSide: theRedSide[2].gamesPlayed, - higherIsBetter: true, - ), - if (greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: t.statCellNum.gamesWonTL.replaceAll(RegExp(r'\n'), " "), - greenSide: theGreenSide[2].gamesWon, - redSide: theRedSide[2].gamesWon, - higherIsBetter: true, - ), - if (greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: "WR %", - greenSide: - theGreenSide[2].winrate * 100, - redSide: theRedSide[2].winrate * 100, - fractionDigits: 2, - higherIsBetter: true, - ), - if (theGreenSide[2].gamesPlayed > 9 && - theRedSide[2].gamesPlayed > 9 && - greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: "Glicko", - greenSide: theGreenSide[2].glicko!, - redSide: theRedSide[2].glicko!, - fractionDigits: 2, - higherIsBetter: true, - ), - if (theGreenSide[2].gamesPlayed > 9 && - theRedSide[2].gamesPlayed > 9 && - greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: "RD", - greenSide: theGreenSide[2].rd!, - redSide: theRedSide[2].rd!, - fractionDigits: 3, - higherIsBetter: false, - ), - if (theGreenSide[2].standing > 0 && - theRedSide[2].standing > 0 && - greenSideMode == Mode.player && - redSideMode == Mode.player) - CompareThingy( - label: t.statCellNum.lbpShort, - greenSide: theGreenSide[2].standing, - redSide: theRedSide[2].standing, - higherIsBetter: false, - ), - if (theGreenSide[2].standingLocal > 0 && - theRedSide[2].standingLocal > 0 && - greenSideMode == Mode.player && - redSideMode == Mode.player) - CompareThingy( - label: t.statCellNum.lbpcShort, - greenSide: - theGreenSide[2].standingLocal, - redSide: theRedSide[2].standingLocal, - higherIsBetter: false, - ), - if (theGreenSide[2].apm != null && - theRedSide[2].apm != null) - CompareThingy( - label: "APM", - greenSide: theGreenSide[2].apm!, - redSide: theRedSide[2].apm!, - fractionDigits: 2, - higherIsBetter: true, - ), - if (theGreenSide[2].pps != null && - theRedSide[2].pps != null) - CompareThingy( - label: "PPS", - greenSide: theGreenSide[2].pps!, - redSide: theRedSide[2].pps!, - fractionDigits: 2, - higherIsBetter: true, - ), - if (theGreenSide[2].vs != null && - theRedSide[2].vs != null) - CompareThingy( - label: "VS", - greenSide: theGreenSide[2].vs!, - redSide: theRedSide[2].vs!, - fractionDigits: 2, - higherIsBetter: true, - ), - ], - ) - : CompareBoolThingy( - greenSide: theGreenSide[2].gamesPlayed > 0, - redSide: theRedSide[2].gamesPlayed > 0, - label: t.playedTL, - trueIsBetter: false), - const Divider(), - if (theGreenSide[2].nerdStats != null && - theRedSide[2].nerdStats != null) - Column( - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(t.nerdStats, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - ), - CompareThingy( - label: "APP", - greenSide: theGreenSide[2].nerdStats!.app, - redSide: theRedSide[2].nerdStats!.app, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "VS/APM", - greenSide: theGreenSide[2].nerdStats!.vsapm, - redSide: theRedSide[2].nerdStats!.vsapm, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "DS/S", - greenSide: theGreenSide[2].nerdStats!.dss, - redSide: theRedSide[2].nerdStats!.dss, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "DS/P", - greenSide: theGreenSide[2].nerdStats!.dsp, - redSide: theRedSide[2].nerdStats!.dsp, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "APP + DS/P", - greenSide: - theGreenSide[2].nerdStats!.appdsp, - redSide: theRedSide[2].nerdStats!.appdsp, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), - greenSide: - theGreenSide[2].nerdStats!.cheese, - redSide: theRedSide[2].nerdStats!.cheese, - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: "Gb Eff.", - greenSide: theGreenSide[2].nerdStats!.gbe, - redSide: theRedSide[2].nerdStats!.gbe, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "wAPP", - greenSide: - theGreenSide[2].nerdStats!.nyaapp, - redSide: theRedSide[2].nerdStats!.nyaapp, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Area", - greenSide: theGreenSide[2].nerdStats!.area, - redSide: theRedSide[2].nerdStats!.area, - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: t.statCellNum.estOfTRShort, - greenSide: theGreenSide[2].estTr!.esttr, - redSide: theRedSide[2].estTr!.esttr, - fractionDigits: 2, - higherIsBetter: true, - ), - if (theGreenSide[2].gamesPlayed > 9 && - theGreenSide[2].gamesPlayed > 9 && - greenSideMode != Mode.stats && - redSideMode != Mode.stats) - CompareThingy( - label: t.statCellNum.accOfEstShort, - greenSide: theGreenSide[2].esttracc!, - redSide: theRedSide[2].esttracc!, - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: "Opener", - greenSide: theGreenSide[2].playstyle!.opener, - redSide: theRedSide[2].playstyle!.opener, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Plonk", - greenSide: theGreenSide[2].playstyle!.plonk, - redSide: theRedSide[2].playstyle!.plonk, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Stride", - greenSide: theGreenSide[2].playstyle!.stride, - redSide: theRedSide[2].playstyle!.stride, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Inf. DS", - greenSide: theGreenSide[2].playstyle!.infds, - redSide: theRedSide[2].playstyle!.infds, - fractionDigits: 3, - higherIsBetter: true, - ), - VsGraphs(theGreenSide[2].apm!, theGreenSide[2].pps!, theGreenSide[2].vs!, theGreenSide[2].nerdStats!, theGreenSide[2].playstyle!, theRedSide[2].apm!, theRedSide[2].pps!, theRedSide[2].vs!, theRedSide[2].nerdStats!, theRedSide[2].playstyle!), - const Divider(), - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(t.winChance, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - ), - if (greenSideMode != Mode.stats && redSideMode != Mode.stats && - theGreenSide[2].gamesPlayed > 9 && theRedSide[2].gamesPlayed > 9) - CompareThingy( - label: t.byGlicko, - greenSide: getWinrateByTR( - theGreenSide[2].glicko!, - theGreenSide[2].rd!, - theRedSide[2].glicko!, - theRedSide[2].rd!) * - 100, - redSide: getWinrateByTR( - theRedSide[2].glicko!, - theRedSide[2].rd!, - theGreenSide[2].glicko!, - theGreenSide[2].rd!) * - 100, - fractionDigits: 2, - higherIsBetter: true, - postfix: "%", - ), - CompareThingy( - label: t.byEstTR, - greenSide: getWinrateByTR( - theGreenSide[2].estTr!.estglicko, - theGreenSide[2].rd ?? noTrRd, - theRedSide[2].estTr!.estglicko, - theRedSide[2].rd ?? noTrRd) * - 100, - redSide: getWinrateByTR( - theRedSide[2].estTr!.estglicko, - theRedSide[2].rd ?? noTrRd, - theGreenSide[2].estTr!.estglicko, - theGreenSide[2].rd ?? noTrRd) * - 100, - fractionDigits: 2, - higherIsBetter: true, - postfix: "%", - ), - ], - ) - ] : [Padding( - padding: const EdgeInsets.all(8.0), - child: Text(t.compareViewNoValues(avgR: "\$avgR"), textAlign: TextAlign.center), - )], // This is so fucked up holy shit - ) + ), + ), ), ), ); @@ -786,6 +796,8 @@ class PlayerSelector extends StatelessWidget { } } +const TextStyle verdictStyle = TextStyle(fontSize: 14, fontFamily: "Eurostile Round Condensed", color: Colors.grey, height: 1.1); + class CompareThingy extends StatelessWidget { final num greenSide; final num redSide; @@ -868,7 +880,7 @@ class CompareThingy extends StatelessWidget { Text( verdict(greenSide, redSide, fractionDigits != null ? fractionDigits! + 2 : 0), - style: const TextStyle(fontSize: 16), + style: verdictStyle, textAlign: TextAlign.center, ) ], @@ -981,11 +993,7 @@ class CompareBoolThingy extends StatelessWidget { style: const TextStyle(fontSize: 22), textAlign: TextAlign.center, ), - const Text( - "---", - style: TextStyle(fontSize: 16), - textAlign: TextAlign.center, - ) + const Text("---", style: verdictStyle, textAlign: TextAlign.center) ], ), Expanded( @@ -1085,10 +1093,7 @@ class CompareDurationThingy extends StatelessWidget { textAlign: TextAlign.center, ), Text( - verdict(greenSide, redSide).toString(), - style: const TextStyle(fontSize: 16), - textAlign: TextAlign.center, - ) + verdict(greenSide, redSide).toString(), style: verdictStyle, textAlign: TextAlign.center) ], ), Expanded( @@ -1176,11 +1181,7 @@ class CompareRegTimeThingy extends StatelessWidget { style: const TextStyle(fontSize: 22), textAlign: TextAlign.center, ), - Text( - verdict(greenSide, redSide), - style: const TextStyle(fontSize: 16), - textAlign: TextAlign.center, - ) + Text(verdict(greenSide, redSide), style: verdictStyle, textAlign: TextAlign.center) ], ), Expanded( diff --git a/lib/views/main_view.dart b/lib/views/main_view.dart index c56a593..3e23981 100644 --- a/lib/views/main_view.dart +++ b/lib/views/main_view.dart @@ -20,6 +20,7 @@ import 'package:tetra_stats/utils/text_shadow.dart'; import 'package:tetra_stats/views/ranks_averages_view.dart' show RankAveragesView; import 'package:tetra_stats/views/tl_leaderboard_view.dart' show TLLeaderboardView; import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView; +import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart'; import 'package:tetra_stats/widgets/search_box.dart'; import 'package:tetra_stats/widgets/stat_sell_num.dart'; import 'package:tetra_stats/widgets/tl_thingy.dart'; @@ -582,18 +583,14 @@ class _TLRecords extends StatelessWidget { style: bigScreen ? const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, shadows: textShadow) : const TextStyle(fontSize: 28, shadows: textShadow)), title: Text("vs. ${data[index].endContext.firstWhere((element) => element.userId != userID).username}"), subtitle: Text(_dateFormat.format(data[index].timestamp)), - trailing: Table(defaultColumnWidth: const IntrinsicColumnWidth(), - defaultVerticalAlignment: TableCellVerticalAlignment.baseline, - textBaseline: TextBaseline.alphabetic, - columnWidths: const { - 0: FixedColumnWidth(50), - 2: FixedColumnWidth(50), - }, - children: [ - TableRow(children: [Text(_f2.format(data[index].endContext.firstWhere((element) => element.userId == userID).secondary), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" :", style: TextStyle(height: 1.1)), Text(_f2.format(data[index].endContext.firstWhere((element) => element.userId != userID).secondary), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" APM", textAlign: TextAlign.right, style: TextStyle(height: 1.1))]), - TableRow(children: [Text(_f2.format(data[index].endContext.firstWhere((element) => element.userId == userID).tertiary), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" :", style: TextStyle(height: 1.1)), Text(_f2.format(data[index].endContext.firstWhere((element) => element.userId != userID).tertiary), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" PPS", textAlign: TextAlign.right, style: TextStyle(height: 1.1))]), - TableRow(children: [Text(_f2.format(data[index].endContext.firstWhere((element) => element.userId == userID).extra), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" :", style: TextStyle(height: 1.1)), Text(_f2.format(data[index].endContext.firstWhere((element) => element.userId != userID).extra), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" VS", textAlign: TextAlign.right, style: TextStyle(height: 1.1))]), - ],), + trailing: TrailingStats( + data[index].endContext.firstWhere((element) => element.userId == userID).secondary, + data[index].endContext.firstWhere((element) => element.userId == userID).tertiary, + data[index].endContext.firstWhere((element) => element.userId == userID).extra, + data[index].endContext.firstWhere((element) => element.userId != userID).secondary, + data[index].endContext.firstWhere((element) => element.userId != userID).tertiary, + data[index].endContext.firstWhere((element) => element.userId != userID).extra + ), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => TlMatchResultView(record: data[index], initPlayerId: userID))), ), ); diff --git a/lib/views/tl_match_view.dart b/lib/views/tl_match_view.dart index 219b725..373441e 100644 --- a/lib/views/tl_match_view.dart +++ b/lib/views/tl_match_view.dart @@ -1,9 +1,11 @@ // ignore_for_file: use_build_context_synchronously import 'dart:io'; +import 'dart:math'; import 'package:tetra_stats/data_objects/tetrio_multiplayer_replay.dart'; import 'package:tetra_stats/services/crud_exceptions.dart'; import 'package:tetra_stats/views/compare_view.dart' show CompareThingy, CompareBoolThingy; +import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart'; import 'package:tetra_stats/widgets/vs_graphs.dart'; import 'main_view.dart' show teto, secs; import 'package:flutter/foundation.dart'; @@ -36,12 +38,10 @@ class TlMatchResultView extends StatefulWidget { } class TlMatchResultState extends State { - late ScrollController _scrollController; late Future replayData; @override void initState(){ - _scrollController = ScrollController(); rounds = [DropdownMenuItem(value: -1, child: Text(t.match))]; rounds.addAll([for (int i = 0; i < widget.record.endContext.first.secondaryTracking.length; i++) DropdownMenuItem(value: i, child: Text(t.roundNumber(n: i+1)))]); replayData = teto.analyzeReplay(widget.record.replayId, widget.record.replayAvalable); @@ -59,10 +59,628 @@ class TlMatchResultState extends State { super.dispose(); } + Widget buildComparison(bool bigScreen, bool showMobileSelector){ + return NestedScrollView( + headerSliverBuilder: (context, value) { + return [ + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 32), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: const [Colors.green, Colors.transparent], + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).success ? 0.4 : 0.0], + )), + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), + child: Column(children: [ + Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username, style: bigScreen ? const TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: 28) : const TextStyle()), + Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).points.toString(), style: const TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: 42)) + ]), + ), + ), + ), + const Padding( + padding: EdgeInsets.only(top: 16), + child: Text("VS"), + ), + Expanded( + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: const [Colors.red, Colors.transparent], + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).success ? 0.4 : 0.0], + )), + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), + child: Column(children: [ + Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username, style: bigScreen ? const TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: 28) : const TextStyle()), + Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).points.toString(), style: const TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: 42)) + ]), + ), + ), + ), + ], + ), + ), + ), + if (showMobileSelector) SliverToBoxAdapter( + child: Center( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text("${t.statsFor}: ", + style: const TextStyle(color: Colors.white, fontSize: 25)), + DropdownButton(items: rounds, value: roundSelector, onChanged: ((value) { + roundSelector = value; + setState(() {}); + }),), + ], + ), + ), + ), + if (widget.record.ownId == widget.record.replayId && showMobileSelector) SliverToBoxAdapter( + child: Center(child: Text(t.p1nkl0bst3rAlert, textAlign: TextAlign.center)), + ), + if (showMobileSelector) SliverToBoxAdapter(child: FutureBuilder(future: replayData, builder: (context, snapshot) { + switch(snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const LinearProgressIndicator(); + case ConnectionState.done: + if (!snapshot.hasError){ + if (roundSelector.isNegative){ + var time = framesToTime(snapshot.data!.totalLength); + return Center(child: Text("${t.matchLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}", textAlign: TextAlign.center)); + }else{ + var time = framesToTime(snapshot.data!.roundLengths[roundSelector]); + return Center(child: Text("${t.roundLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}\n${t.winner}: ${snapshot.data!.roundWinners[roundSelector][1]}", textAlign: TextAlign.center,)); + } + }else{ + String reason; + switch (snapshot.error.runtimeType){ + case ReplayNotAvalable: + reason = t.matchIsTooOld; + break; + case SzyNotFound: + reason = t.matchIsTooOld; + break; + case SzyForbidden: + reason = t.errors.replayRejected; + break; + case SzyTooManyRequests: + reason = t.errors.tooManyRequests; + break; + default: + reason = snapshot.error.toString(); + break; + } + return Text("${t.replayIssue}: $reason", textAlign: TextAlign.center); + } + + } + },),), + const SliverToBoxAdapter( + child: Divider(), + ) + ]; + }, + body: ListView( + children: [ + Column( + children: [ + CompareThingy( + label: "APM", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector], + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector], + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: "PPS", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector], + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector], + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: "VS", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector], + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector], + fractionDigits: 2, + higherIsBetter: true, + ), + FutureBuilder(future: replayData, builder: (BuildContext context, AsyncSnapshot snapshot){ + switch(snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const LinearProgressIndicator(); + case ConnectionState.done: + if (!snapshot.hasError){ + var greenSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId == widget.initPlayerId); + var redSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId != widget.initPlayerId); + return Column(children: [ + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].inputs : snapshot.data!.stats[roundSelector][greenSidePlayer].inputs, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].inputs : snapshot.data!.stats[roundSelector][redSidePlayer].inputs, + label: "Inputs", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][greenSidePlayer].piecesPlaced, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][redSidePlayer].piecesPlaced, + label: "Pieces Placed", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kpp : snapshot.data!.stats[roundSelector][greenSidePlayer].kpp, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kpp : snapshot.data!.stats[roundSelector][redSidePlayer].kpp, + label: "KpP", higherIsBetter: false, fractionDigits: 2,), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kps : snapshot.data!.stats[roundSelector][greenSidePlayer].kps, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kps : snapshot.data!.stats[roundSelector][redSidePlayer].kps, + label: "KpS", higherIsBetter: true, fractionDigits: 2,), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][greenSidePlayer].linesCleared, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared, + label: "Lines Cleared", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].score : snapshot.data!.stats[roundSelector][greenSidePlayer].score, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].score : snapshot.data!.stats[roundSelector][redSidePlayer].score, + label: "Score", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].spp : snapshot.data!.stats[roundSelector][greenSidePlayer].spp, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].spp : snapshot.data!.stats[roundSelector][redSidePlayer].spp, + label: "SpP", higherIsBetter: true, fractionDigits: 2,), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][greenSidePlayer].finessePercentage * 100, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100, + label: "Finnese", postfix: "%", fractionDigits: 2, higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topSpike : snapshot.data!.stats[roundSelector][greenSidePlayer].topSpike, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topSpike : snapshot.data!.stats[roundSelector][redSidePlayer].topSpike, + label: "Best Spike", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topCombo : snapshot.data!.stats[roundSelector][greenSidePlayer].topCombo, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topCombo : snapshot.data!.stats[roundSelector][redSidePlayer].topCombo, + label: "Best Combo", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topBtB : snapshot.data!.stats[roundSelector][greenSidePlayer].topBtB, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topBtB : snapshot.data!.stats[roundSelector][redSidePlayer].topBtB, + label: "Best BtB", higherIsBetter: true), + const Divider(), + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text("Garbage", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), + ), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.sent, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.sent, + label: "Sent", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.recived, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.recived, + label: "Recived", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.attack, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.attack, + label: "Attack", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.cleared, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared, + label: "Cleared", higherIsBetter: true), + const Divider(), + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text("Line Clears", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), + ), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.allClears, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][redSidePlayer].clears.allClears, + label: "PC", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].tspins : snapshot.data!.stats[roundSelector][greenSidePlayer].tspins, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].tspins : snapshot.data!.stats[roundSelector][redSidePlayer].tspins, + label: "T-spins", higherIsBetter: true), + CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.quads, + redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][redSidePlayer].clears.quads, + label: "Quads", higherIsBetter: true), + ],); + }else{ + return Container(); + } + + } + }) + ], + ), + const Divider(), + Column( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(t.nerdStats, + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: bigScreen ? 42 : 28)), + ), + CompareThingy( + label: "APP", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].app, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].app, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "VS/APM", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "DS/S", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dss, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dss, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "DS/P", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dsp, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dsp, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "APP + DS/P", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].cheese, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].cheese, + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: "Gb Eff.", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].gbe, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].gbe, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "wAPP", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Area", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].area, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].area, + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: t.statCellNum.estOfTRShort, + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTrTracking[roundSelector].esttr, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTrTracking[roundSelector].esttr, + fractionDigits: 2, + higherIsBetter: true, + ), + CompareThingy( + label: "Opener", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].opener, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].opener, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Plonk", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].plonk, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].plonk, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Stride", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].stride, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].stride, + fractionDigits: 3, + higherIsBetter: true, + ), + CompareThingy( + label: "Inf. DS", + greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].infds, + redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].infds, + fractionDigits: 3, + higherIsBetter: true, + ), + VsGraphs( + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector], + roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector] + ) + ], + ), + if (widget.record.ownId != widget.record.replayId) const Divider(), + if (widget.record.ownId != widget.record.replayId) Column( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text("Handling", + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: bigScreen ? 42 : 28)), + ), + CompareThingy( + greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.das, + redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.das, + label: "DAS", fractionDigits: 1, postfix: "F", + higherIsBetter: false), + CompareThingy( + greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.arr, + redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.arr, + label: "ARR", fractionDigits: 1, postfix: "F", + higherIsBetter: false), + CompareThingy( + greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.sdf, + redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.sdf, + label: "SDF", prefix: "x", + higherIsBetter: true), + CompareBoolThingy( + greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.safeLock, + redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.safeLock, + label: "Safe HD", + trueIsBetter: true) + ], + ) + ], + ) + ); + } + + Widget buildRoundSelector(double width){ + return Padding( + padding: EdgeInsets.all(8.0000000), + child: SizedBox( + width: width, + child: NestedScrollView( + headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { + return [ + SliverToBoxAdapter(child: + Wrap( + alignment: WrapAlignment.spaceBetween, + children: [ + FutureBuilder(future: replayData, builder: (context, snapshot) { + switch(snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const CircularProgressIndicator(); + case ConnectionState.done: + if (!snapshot.hasError){ + var time = framesToTime(snapshot.data!.totalLength); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(t.matchLength), + RichText( + text: TextSpan( + text: "${time.inMinutes}:${NumberFormat("00", LocaleSettings.currentLocale.languageCode).format(time.inSeconds%60)}", + style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, fontWeight: FontWeight.w500), + children: [TextSpan(text: ".${NumberFormat("000", LocaleSettings.currentLocale.languageCode).format(time.inMilliseconds%1000)}", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))] + ), + ) + ],); + }else{ + String reason; + switch (snapshot.error.runtimeType){ + case ReplayNotAvalable: + reason = t.matchIsTooOld; + break; + case SzyNotFound: + reason = t.matchIsTooOld; + break; + case SzyForbidden: + reason = t.errors.replayRejected; + break; + case SzyTooManyRequests: + reason = t.errors.tooManyRequests; + break; + default: + reason = snapshot.error.toString(); + break; + } + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.record.ownId != widget.record.replayId) Text("${t.replayIssue}: $reason"), + if (widget.record.ownId == widget.record.replayId) Center(child: Text(t.p1nkl0bst3rAlert, textAlign: TextAlign.center)), + if (widget.record.ownId != widget.record.replayId) RichText( + text: TextSpan( + text: "-:--", + style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, fontWeight: FontWeight.w500, color: Colors.grey), + children: [TextSpan(text: ".---", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))] + ), + ) + ],); + } + + } + },), + if (widget.record.ownId != widget.record.replayId) Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text("Number of rounds"), + RichText( + text: TextSpan( + text: widget.record.endContext.first.secondaryTracking.length > 0 ? widget.record.endContext.first.secondaryTracking.length.toString() : "---", + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: 28, + fontWeight: FontWeight.w500, + color: widget.record.endContext.first.secondaryTracking.length == 0 ? Colors.grey : null + ), + ), + ) + ],), + Column(children: [ + OverflowBar( + alignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( child: const Text('Match stats'), + style: roundSelector == -1 ? ButtonStyle(backgroundColor: MaterialStatePropertyAll(Colors.grey.shade900)) : null, + onPressed: () { + roundSelector = -1; + setState(() {}); + }), + TextButton( child: const Text('Time-weighted match stats'), onPressed: () { + roundSelector = -1; + setState(() {}); + }), + //TextButton( child: const Text('Button 3'), onPressed: () {}), + ], + ) + ]), + // Column( + // children: [ + // ListTile( + // leading: Text("Round time"), + // title: Text("Winner", textAlign: TextAlign.center,), + // trailing: Text("Round stats"), + // ) + // ], + // ) + ], + ) + ) + ]; + }, + body: ListView.builder(itemCount: widget.record.endContext.first.secondaryTracking.length, + itemBuilder: (BuildContext context, int index) { + return FutureBuilder(future: replayData, builder: (context, snapshot) { + switch(snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const LinearProgressIndicator(); + case ConnectionState.done: + if (!snapshot.hasError){ + var time = framesToTime(snapshot.data!.roundLengths[index]); + var accentColor = snapshot.data!.roundWinners[index][0] == widget.initPlayerId ? Colors.green : Colors.red; + var bgColor = roundSelector == index ? Colors.grey.shade900 : Colors.transparent; + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + stops: const [0, 0.05], + colors: [accentColor, bgColor] + ) + ), + child: ListTile( + leading:RichText( + text: TextSpan( + text: "${time.inMinutes}:${NumberFormat("00", LocaleSettings.currentLocale.languageCode).format(time.inSeconds%60)}", + style: TextStyle(fontFamily: "Eurostile Round", fontSize: 22, fontWeight: FontWeight.w500), + children: [TextSpan(text: ".${NumberFormat("000", LocaleSettings.currentLocale.languageCode).format(time.inMilliseconds%1000)}", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))] + ), + ), + title: Text(snapshot.data!.roundWinners[index][1], textAlign: TextAlign.center), + trailing: TrailingStats( + widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[index], + widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[index] + ), + onTap:(){ + roundSelector = index; + setState(() {}); + }, + ), + ); + }else{ + return Container( + decoration: BoxDecoration( + color: roundSelector == index ? Colors.grey.shade900 : Colors.transparent + ), + child: ListTile( + leading: RichText( + text: TextSpan( + text: "-:--", + style: TextStyle(fontFamily: "Eurostile Round", fontSize: 22, fontWeight: FontWeight.w500, color: Colors.grey), + children: [TextSpan(text: ".---", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))] + ), + ), + title: Text("---", style: TextStyle(color: Colors.grey), textAlign: TextAlign.center), + trailing: TrailingStats( + widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[index], + widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[index], + widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[index] + ), + onTap:(){ + roundSelector = index; + setState(() {}); + }, + ), + ); + } + } + } + ); + }) + ), + ), + ); + } + + Widget getMainWidget(double viewportWidth) { + if (viewportWidth <= 1024) { + return Center( + child: Container( + constraints: BoxConstraints(maxWidth: 768), + child: buildComparison(viewportWidth > 768, true) + ), + ); + } else { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + //mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 768, + child: buildComparison(true, false) + ), + Container( + constraints: BoxConstraints(maxWidth: 768), + child: buildRoundSelector(max(viewportWidth-768-16, 200)), + ) + ], + ); + } + } + @override Widget build(BuildContext context) { final t = Translations.of(context); - bool bigScreen = MediaQuery.of(context).size.width > 768; return Scaffold( appBar: AppBar( title: Text("${widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username.toUpperCase()} ${t.vs} ${widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username.toUpperCase()} ${t.inTLmatch} ${dateFormat.format(widget.record.timestamp)}"), @@ -114,401 +732,7 @@ class TlMatchResultState extends State { ] ), backgroundColor: Colors.black, - body: SafeArea( - child: NestedScrollView( - controller: _scrollController, - headerSliverBuilder: (context, value) { - return [ - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.fromLTRB(16, 16, 16, 32), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: const [Colors.green, Colors.transparent], - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).success ? 0.4 : 0.0], - )), - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), - child: Column(children: [ - Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username, style: bigScreen ? const TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: 28) : const TextStyle()), - Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).points.toString(), style: const TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: 42)) - ]), - ), - ), - ), - const Padding( - padding: EdgeInsets.only(top: 16), - child: Text("VS"), - ), - Expanded( - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: const [Colors.red, Colors.transparent], - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).success ? 0.4 : 0.0], - )), - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), - child: Column(children: [ - Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username, style: bigScreen ? const TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: 28) : const TextStyle()), - Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).points.toString(), style: const TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: 42)) - ]), - ), - ), - ), - ], - ), - ), - ), - SliverToBoxAdapter( - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.baseline, - textBaseline: TextBaseline.alphabetic, - children: [ - Text("${t.statsFor}: ", - style: const TextStyle(color: Colors.white, fontSize: 25)), - DropdownButton(items: rounds, value: roundSelector, onChanged: ((value) { - roundSelector = value; - setState(() {}); - }),), - ], - ), - ), - ), - if (widget.record.ownId == widget.record.replayId) SliverToBoxAdapter( - child: Center(child: Text(t.p1nkl0bst3rAlert, textAlign: TextAlign.center)), - ), - SliverToBoxAdapter(child: FutureBuilder(future: replayData, builder: (context, snapshot) { - switch(snapshot.connectionState){ - case ConnectionState.none: - case ConnectionState.waiting: - case ConnectionState.active: - return const LinearProgressIndicator(); - case ConnectionState.done: - if (!snapshot.hasError){ - if (roundSelector.isNegative){ - var time = framesToTime(snapshot.data!.totalLength); - return Center(child: Text("${t.matchLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}", textAlign: TextAlign.center)); - }else{ - var time = framesToTime(snapshot.data!.roundLengths[roundSelector]); - return Center(child: Text("${t.roundLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}\n${t.winner}: ${snapshot.data!.roundWinners[roundSelector][1]}", textAlign: TextAlign.center,)); - } - }else{ - String reason; - switch (snapshot.error.runtimeType){ - case ReplayNotAvalable: - reason = t.matchIsTooOld; - break; - case SzyNotFound: - reason = t.matchIsTooOld; - break; - case SzyForbidden: - reason = t.errors.replayRejected; - break; - case SzyTooManyRequests: - reason = t.errors.tooManyRequests; - break; - default: - reason = snapshot.error.toString(); - break; - } - return Text("${t.replayIssue}: $reason", textAlign: TextAlign.center); - } - - } - },),), - const SliverToBoxAdapter( - child: Divider(), - ) - ]; - }, - body: ListView( - children: [ - Column( - children: [ - CompareThingy( - label: "APM", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector], - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector], - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: "PPS", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector], - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector], - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: "VS", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector], - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector], - fractionDigits: 2, - higherIsBetter: true, - ), - FutureBuilder(future: replayData, builder: (BuildContext context, AsyncSnapshot snapshot){ - switch(snapshot.connectionState){ - case ConnectionState.none: - case ConnectionState.waiting: - case ConnectionState.active: - return const LinearProgressIndicator(); - case ConnectionState.done: - if (!snapshot.hasError){ - var greenSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId == widget.initPlayerId); - var redSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId != widget.initPlayerId); - return Column(children: [ - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].inputs : snapshot.data!.stats[roundSelector][greenSidePlayer].inputs, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].inputs : snapshot.data!.stats[roundSelector][redSidePlayer].inputs, - label: "Inputs", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][greenSidePlayer].piecesPlaced, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][redSidePlayer].piecesPlaced, - label: "Pieces Placed", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kpp : snapshot.data!.stats[roundSelector][greenSidePlayer].kpp, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kpp : snapshot.data!.stats[roundSelector][redSidePlayer].kpp, - label: "KpP", higherIsBetter: false, fractionDigits: 2,), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kps : snapshot.data!.stats[roundSelector][greenSidePlayer].kps, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kps : snapshot.data!.stats[roundSelector][redSidePlayer].kps, - label: "KpS", higherIsBetter: true, fractionDigits: 2,), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][greenSidePlayer].linesCleared, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared, - label: "Lines Cleared", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].score : snapshot.data!.stats[roundSelector][greenSidePlayer].score, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].score : snapshot.data!.stats[roundSelector][redSidePlayer].score, - label: "Score", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].spp : snapshot.data!.stats[roundSelector][greenSidePlayer].spp, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].spp : snapshot.data!.stats[roundSelector][redSidePlayer].spp, - label: "SpP", higherIsBetter: true, fractionDigits: 2,), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][greenSidePlayer].finessePercentage * 100, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100, - label: "Finnese", postfix: "%", fractionDigits: 2, higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topSpike : snapshot.data!.stats[roundSelector][greenSidePlayer].topSpike, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topSpike : snapshot.data!.stats[roundSelector][redSidePlayer].topSpike, - label: "Best Spike", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topCombo : snapshot.data!.stats[roundSelector][greenSidePlayer].topCombo, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topCombo : snapshot.data!.stats[roundSelector][redSidePlayer].topCombo, - label: "Best Combo", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topBtB : snapshot.data!.stats[roundSelector][greenSidePlayer].topBtB, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topBtB : snapshot.data!.stats[roundSelector][redSidePlayer].topBtB, - label: "Best BtB", higherIsBetter: true), - const Divider(), - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text("Garbage", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), - ), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.sent, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.sent, - label: "Sent", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.recived, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.recived, - label: "Recived", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.attack, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.attack, - label: "Attack", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.cleared, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared, - label: "Cleared", higherIsBetter: true), - const Divider(), - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text("Line Clears", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), - ), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.allClears, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][redSidePlayer].clears.allClears, - label: "PC", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].tspins : snapshot.data!.stats[roundSelector][greenSidePlayer].tspins, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].tspins : snapshot.data!.stats[roundSelector][redSidePlayer].tspins, - label: "T-spins", higherIsBetter: true), - CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.quads, - redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][redSidePlayer].clears.quads, - label: "Quads", higherIsBetter: true), - ],); - }else{ - return Container(); - } - - } - }) - ], - ), - const Divider(), - Column( - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(t.nerdStats, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - ), - CompareThingy( - label: "APP", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].app, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].app, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "VS/APM", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "DS/S", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dss, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dss, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "DS/P", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dsp, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dsp, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "APP + DS/P", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].cheese, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].cheese, - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: "Gb Eff.", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].gbe, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].gbe, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "wAPP", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Area", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].area, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].area, - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: t.statCellNum.estOfTRShort, - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTrTracking[roundSelector].esttr, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTrTracking[roundSelector].esttr, - fractionDigits: 2, - higherIsBetter: true, - ), - CompareThingy( - label: "Opener", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].opener, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].opener, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Plonk", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].plonk, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].plonk, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Stride", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].stride, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].stride, - fractionDigits: 3, - higherIsBetter: true, - ), - CompareThingy( - label: "Inf. DS", - greenSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].infds, - redSide: roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].infds, - fractionDigits: 3, - higherIsBetter: true, - ), - VsGraphs( - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector], - roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector] - ) - ], - ), - if (widget.record.ownId != widget.record.replayId) const Divider(), - if (widget.record.ownId != widget.record.replayId) Column( - children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text("Handling", - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - ), - CompareThingy( - greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.das, - redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.das, - label: "DAS", fractionDigits: 1, postfix: "F", - higherIsBetter: false), - CompareThingy( - greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.arr, - redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.arr, - label: "ARR", fractionDigits: 1, postfix: "F", - higherIsBetter: false), - CompareThingy( - greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.sdf, - redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.sdf, - label: "SDF", prefix: "x", - higherIsBetter: true), - CompareBoolThingy( - greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.safeLock, - redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.safeLock, - label: "Safe HD", - trueIsBetter: true) - ], - ) - ], - ) - ), - ), - ); + body: getMainWidget(MediaQuery.of(context).size.width), + ); } } diff --git a/lib/widgets/list_tile_trailing_stats.dart b/lib/widgets/list_tile_trailing_stats.dart new file mode 100644 index 0000000..52db4b9 --- /dev/null +++ b/lib/widgets/list_tile_trailing_stats.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:tetra_stats/gen/strings.g.dart'; + +class TrailingStats extends StatelessWidget{ + final double yourAPM; + final double yourPPS; + final double yourVS; + final double notyourAPM; + final double notyourPPS; + final double notyourVS; + + const TrailingStats(this.yourAPM, this.yourPPS, this.yourVS, this.notyourAPM, this.notyourPPS, this.notyourVS, {super.key}); + + @override + Widget build(BuildContext context) { + final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2); + return Table( + defaultColumnWidth: const IntrinsicColumnWidth(), + defaultVerticalAlignment: TableCellVerticalAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + columnWidths: const { + 0: FixedColumnWidth(42), + 2: FixedColumnWidth(42), + }, + children: [ + TableRow(children: [Text(f2.format(yourAPM), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" :", style: TextStyle(height: 1.1)), Text(f2.format(notyourAPM), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" APM", textAlign: TextAlign.right, style: TextStyle(height: 1.1))]), + TableRow(children: [Text(f2.format(yourPPS), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" :", style: TextStyle(height: 1.1)), Text(f2.format(notyourPPS), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" PPS", textAlign: TextAlign.right, style: TextStyle(height: 1.1))]), + TableRow(children: [Text(f2.format(yourVS), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" :", style: TextStyle(height: 1.1)), Text(f2.format(notyourVS), textAlign: TextAlign.right, style: const TextStyle(height: 1.1)), const Text(" VS", textAlign: TextAlign.right, style: TextStyle(height: 1.1))]), + ], + ); + } +} \ No newline at end of file