40 Lines & Blitz tab design
This commit is contained in:
parent
fa8d0052d4
commit
c1f0e85b4a
|
@ -4,9 +4,9 @@
|
||||||
/// To regenerate, run: `dart run slang`
|
/// To regenerate, run: `dart run slang`
|
||||||
///
|
///
|
||||||
/// Locales: 2
|
/// Locales: 2
|
||||||
/// Strings: 1018 (509 per locale)
|
/// Strings: 1050 (525 per locale)
|
||||||
///
|
///
|
||||||
/// Built on 2024-02-08 at 20:30 UTC
|
/// Built on 2024-03-18 at 17:41 UTC
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
|
@ -675,8 +675,30 @@ class _StringsNumOfGameActionsEn {
|
||||||
// Translations
|
// Translations
|
||||||
String get pc => 'All Clears';
|
String get pc => 'All Clears';
|
||||||
String get hold => 'Holds';
|
String get hold => 'Holds';
|
||||||
String get tspinsTotal => 'T-spins total';
|
String inputs({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||||
String get lineClears => 'Line clears';
|
zero: '${n} key presses',
|
||||||
|
one: '${n} key press',
|
||||||
|
two: '${n} key presses',
|
||||||
|
few: '${n} key presses',
|
||||||
|
many: '${n} key presses',
|
||||||
|
other: '${n} key presses',
|
||||||
|
);
|
||||||
|
String tspinsTotal({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||||
|
zero: '${n} T-spins total',
|
||||||
|
one: '${n} T-spin total',
|
||||||
|
two: '${n} T-spins total',
|
||||||
|
few: '${n} T-spins total',
|
||||||
|
many: '${n} T-spins total',
|
||||||
|
other: '${n} T-spins total',
|
||||||
|
);
|
||||||
|
String lineClears({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||||
|
zero: '${n} lines cleared',
|
||||||
|
one: '${n} line cleared',
|
||||||
|
two: '${n} lines cleared',
|
||||||
|
few: '${n} lines cleared',
|
||||||
|
many: '${n} lines cleared',
|
||||||
|
other: '${n} lines cleared',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path: popupActions
|
// Path: popupActions
|
||||||
|
@ -1268,8 +1290,30 @@ class _StringsNumOfGameActionsRu implements _StringsNumOfGameActionsEn {
|
||||||
// Translations
|
// Translations
|
||||||
@override String get pc => 'Все чисто';
|
@override String get pc => 'Все чисто';
|
||||||
@override String get hold => 'В запас';
|
@override String get hold => 'В запас';
|
||||||
@override String get tspinsTotal => 'T-spins всего';
|
@override String inputs({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||||
@override String get lineClears => 'Линий очищено';
|
zero: '${n} нажатий клавиш',
|
||||||
|
one: '${n} нажатие на клавишу',
|
||||||
|
two: '${n} нажатия на клавишы',
|
||||||
|
few: '${n} нажатия на клавишы',
|
||||||
|
many: '${n} нажатий на клавиш',
|
||||||
|
other: '${n} нажатий на клавиш',
|
||||||
|
);
|
||||||
|
@override String tspinsTotal({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||||
|
zero: '${n} T-спинов всего',
|
||||||
|
one: 'всего ${n} T-спин',
|
||||||
|
two: '${n} T-спина всего',
|
||||||
|
few: '${n} T-спина всего',
|
||||||
|
many: '${n} T-спинов всего',
|
||||||
|
other: '${n} T-спинов всего',
|
||||||
|
);
|
||||||
|
@override String lineClears({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||||
|
zero: '${n} линий очищено',
|
||||||
|
one: '${n} линия очищена',
|
||||||
|
two: '${n} линии очищено',
|
||||||
|
few: '${n} линии очищено',
|
||||||
|
many: '${n} линий очищено',
|
||||||
|
other: '${n} линий очищено',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path: popupActions
|
// Path: popupActions
|
||||||
|
@ -1546,8 +1590,30 @@ extension on Translations {
|
||||||
case 'playerRole.anon': return 'Anonymous';
|
case 'playerRole.anon': return 'Anonymous';
|
||||||
case 'numOfGameActions.pc': return 'All Clears';
|
case 'numOfGameActions.pc': return 'All Clears';
|
||||||
case 'numOfGameActions.hold': return 'Holds';
|
case 'numOfGameActions.hold': return 'Holds';
|
||||||
case 'numOfGameActions.tspinsTotal': return 'T-spins total';
|
case 'numOfGameActions.inputs': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||||
case 'numOfGameActions.lineClears': return 'Line clears';
|
zero: '${n} key presses',
|
||||||
|
one: '${n} key press',
|
||||||
|
two: '${n} key presses',
|
||||||
|
few: '${n} key presses',
|
||||||
|
many: '${n} key presses',
|
||||||
|
other: '${n} key presses',
|
||||||
|
);
|
||||||
|
case 'numOfGameActions.tspinsTotal': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||||
|
zero: '${n} T-spins total',
|
||||||
|
one: '${n} T-spin total',
|
||||||
|
two: '${n} T-spins total',
|
||||||
|
few: '${n} T-spins total',
|
||||||
|
many: '${n} T-spins total',
|
||||||
|
other: '${n} T-spins total',
|
||||||
|
);
|
||||||
|
case 'numOfGameActions.lineClears': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||||
|
zero: '${n} lines cleared',
|
||||||
|
one: '${n} line cleared',
|
||||||
|
two: '${n} lines cleared',
|
||||||
|
few: '${n} lines cleared',
|
||||||
|
many: '${n} lines cleared',
|
||||||
|
other: '${n} lines cleared',
|
||||||
|
);
|
||||||
case 'popupActions.cancel': return 'Cancel';
|
case 'popupActions.cancel': return 'Cancel';
|
||||||
case 'popupActions.submit': return 'Submit';
|
case 'popupActions.submit': return 'Submit';
|
||||||
case 'popupActions.ok': return 'OK';
|
case 'popupActions.ok': return 'OK';
|
||||||
|
@ -2065,8 +2131,30 @@ extension on _StringsRu {
|
||||||
case 'playerRole.anon': return 'Аноним';
|
case 'playerRole.anon': return 'Аноним';
|
||||||
case 'numOfGameActions.pc': return 'Все чисто';
|
case 'numOfGameActions.pc': return 'Все чисто';
|
||||||
case 'numOfGameActions.hold': return 'В запас';
|
case 'numOfGameActions.hold': return 'В запас';
|
||||||
case 'numOfGameActions.tspinsTotal': return 'T-spins всего';
|
case 'numOfGameActions.inputs': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||||
case 'numOfGameActions.lineClears': return 'Линий очищено';
|
zero: '${n} нажатий клавиш',
|
||||||
|
one: '${n} нажатие на клавишу',
|
||||||
|
two: '${n} нажатия на клавишы',
|
||||||
|
few: '${n} нажатия на клавишы',
|
||||||
|
many: '${n} нажатий на клавиш',
|
||||||
|
other: '${n} нажатий на клавиш',
|
||||||
|
);
|
||||||
|
case 'numOfGameActions.tspinsTotal': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||||
|
zero: '${n} T-спинов всего',
|
||||||
|
one: 'всего ${n} T-спин',
|
||||||
|
two: '${n} T-спина всего',
|
||||||
|
few: '${n} T-спина всего',
|
||||||
|
many: '${n} T-спинов всего',
|
||||||
|
other: '${n} T-спинов всего',
|
||||||
|
);
|
||||||
|
case 'numOfGameActions.lineClears': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||||
|
zero: '${n} линий очищено',
|
||||||
|
one: '${n} линия очищена',
|
||||||
|
two: '${n} линии очищено',
|
||||||
|
few: '${n} линии очищено',
|
||||||
|
many: '${n} линий очищено',
|
||||||
|
other: '${n} линий очищено',
|
||||||
|
);
|
||||||
case 'popupActions.cancel': return 'Отменить';
|
case 'popupActions.cancel': return 'Отменить';
|
||||||
case 'popupActions.submit': return 'Подтвердить';
|
case 'popupActions.submit': return 'Подтвердить';
|
||||||
case 'popupActions.ok': return 'OK';
|
case 'popupActions.ok': return 'OK';
|
||||||
|
|
|
@ -4,5 +4,6 @@ import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
final NumberFormat comparef = NumberFormat("+#,###.###;-#,###.###")..maximumFractionDigits = 3;
|
final NumberFormat comparef = NumberFormat("+#,###.###;-#,###.###")..maximumFractionDigits = 3;
|
||||||
final NumberFormat intf = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0);
|
final NumberFormat intf = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0);
|
||||||
final NumberFormat f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 4);
|
final NumberFormat f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 4);
|
||||||
final NumberFormat f3 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 3);
|
final NumberFormat f3 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 3);
|
||||||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
||||||
|
final NumberFormat f2l = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2)..minimumFractionDigits = 0;
|
|
@ -21,6 +21,8 @@ import 'package:tetra_stats/utils/text_shadow.dart';
|
||||||
import 'package:tetra_stats/views/ranks_averages_view.dart' show RankAveragesView;
|
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_leaderboard_view.dart' show TLLeaderboardView;
|
||||||
import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView;
|
import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView;
|
||||||
|
import 'package:tetra_stats/widgets/finesse_thingy.dart';
|
||||||
|
import 'package:tetra_stats/widgets/lineclears_thingy.dart';
|
||||||
import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart';
|
import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart';
|
||||||
import 'package:tetra_stats/widgets/search_box.dart';
|
import 'package:tetra_stats/widgets/search_box.dart';
|
||||||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||||
|
@ -437,7 +439,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
child: _TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0)
|
child: _TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0)
|
||||||
),
|
),
|
||||||
],),
|
],),
|
||||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
_History(chartsData: chartsData, states: snapshot.data![2], changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||||
_TwoRecordsThingy(sprint: snapshot.data![1]['sprint'], blitz: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank,),
|
_TwoRecordsThingy(sprint: snapshot.data![1]['sprint'], blitz: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank,),
|
||||||
// Row(children: [
|
// Row(children: [
|
||||||
// Container(
|
// Container(
|
||||||
|
@ -464,7 +466,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
lbPositions: meAmongEveryone
|
lbPositions: meAmongEveryone
|
||||||
),
|
),
|
||||||
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
_History(chartsData: chartsData, states: snapshot.data![2], changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||||
_RecordThingy(record: snapshot.data![1]['sprint'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
_RecordThingy(record: snapshot.data![1]['sprint'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
||||||
_RecordThingy(record: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
_RecordThingy(record: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
||||||
_OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],)
|
_OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],)
|
||||||
|
@ -696,6 +698,7 @@ class _TLRecords extends StatelessWidget {
|
||||||
|
|
||||||
class _History extends StatelessWidget{
|
class _History extends StatelessWidget{
|
||||||
final List<DropdownMenuItem<List<FlSpot>>> chartsData;
|
final List<DropdownMenuItem<List<FlSpot>>> chartsData;
|
||||||
|
final List<TetrioPlayer> states;
|
||||||
final String userID;
|
final String userID;
|
||||||
final Function update;
|
final Function update;
|
||||||
final Function changePlayer;
|
final Function changePlayer;
|
||||||
|
@ -703,7 +706,7 @@ class _History extends StatelessWidget{
|
||||||
|
|
||||||
/// Widget, that can show history of some stat of the player on the graph.
|
/// Widget, that can show history of some stat of the player on the graph.
|
||||||
/// Requires player [states], which is list of states and function [update], which rebuild widgets
|
/// Requires player [states], which is list of states and function [update], which rebuild widgets
|
||||||
const _History({required this.chartsData, required this.userID, required this.changePlayer, required this.update, required this.wasActiveInTL});
|
const _History({required this.chartsData, required this.states, required this.userID, required this.changePlayer, required this.update, required this.wasActiveInTL});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -1017,6 +1020,23 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _HistoryTableThingy extends StatelessWidget{
|
||||||
|
final List<TetrioPlayer> states;
|
||||||
|
|
||||||
|
const _HistoryTableThingy(this.states);
|
||||||
|
// :tf:
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return LayoutBuilder(builder: (context, constraints){
|
||||||
|
return SingleChildScrollView(child: Table(
|
||||||
|
children: [
|
||||||
|
TableRow(children: [Text("Date & Time"), Text("Tr")]),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _TwoRecordsThingy extends StatelessWidget {
|
class _TwoRecordsThingy extends StatelessWidget {
|
||||||
final RecordSingle? sprint;
|
final RecordSingle? sprint;
|
||||||
final RecordSingle? blitz;
|
final RecordSingle? blitz;
|
||||||
|
@ -1081,6 +1101,9 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
if (rank != null && rank != "z") TextSpan(text: "${readableTimeDifference(sprint!.endContext!.finalTime, sprintAverages[rank]!)} ${sprintBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average\n", style: TextStyle(
|
if (rank != null && rank != "z") TextSpan(text: "${readableTimeDifference(sprint!.endContext!.finalTime, sprintAverages[rank]!)} ${sprintBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
color: sprintBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
color: sprintBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
||||||
|
))
|
||||||
|
else TextSpan(text: "${readableTimeDifference(sprint!.endContext!.finalTime, closestAverageSprint.value)} ${sprintBetterThanClosestAverage ? "better" : "worse"} than ${closestAverageSprint.key.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
|
color: sprintBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
||||||
)),
|
)),
|
||||||
if (sprint!.rank != null) TextSpan(text: "№${sprint!.rank}", style: TextStyle(color: getColorOfRank(sprint!.rank!))),
|
if (sprint!.rank != null) TextSpan(text: "№${sprint!.rank}", style: TextStyle(color: getColorOfRank(sprint!.rank!))),
|
||||||
if (sprint!.rank != null) const TextSpan(text: " • "),
|
if (sprint!.rank != null) const TextSpan(text: " • "),
|
||||||
|
@ -1096,17 +1119,20 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
alignment: WrapAlignment.spaceBetween,
|
alignment: WrapAlignment.spaceBetween,
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
children: [
|
children: [
|
||||||
StatCellNum(playerStat: sprint!.endContext!.piecesPlaced, playerStatLabel: t.statCellNum.pieces, isScreenBig: true, higherIsBetter: true),
|
StatCellNum(playerStat: sprint!.endContext!.piecesPlaced, playerStatLabel: t.statCellNum.pieces, isScreenBig: true, higherIsBetter: true, smallDecimal: false),
|
||||||
StatCellNum(playerStat: sprint!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: true, higherIsBetter: true),
|
StatCellNum(playerStat: sprint!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: true, higherIsBetter: true, smallDecimal: false),
|
||||||
StatCellNum(playerStat: sprint!.endContext!.kps, playerStatLabel: t.statCellNum.kps, fractionDigits: 2, isScreenBig: true, higherIsBetter: true,)
|
StatCellNum(playerStat: sprint!.endContext!.kpp, playerStatLabel: t.statCellNum.kpp, fractionDigits: 2, isScreenBig: true, higherIsBetter: true, smallDecimal: false),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (sprint != null) FinesseThingy(sprint?.endContext?.finesse, sprint?.endContext?.finessePercentage),
|
||||||
|
if (sprint != null) LineclearsThingy(sprint!.endContext!.clears, sprint!.endContext!.lines, sprint!.endContext!.holds, sprint!.endContext!.tSpins),
|
||||||
|
if (sprint != null) Text("${sprint!.endContext!.inputs} KP • ${f2.format(sprint!.endContext!.kps)} KpS")
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -1133,6 +1159,9 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
if (rank != null && rank != "z") TextSpan(text: "${readableIntDifference(blitz!.endContext!.score, blitzAverages[rank]!)} ${blitzBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average\n", style: TextStyle(
|
if (rank != null && rank != "z") TextSpan(text: "${readableIntDifference(blitz!.endContext!.score, blitzAverages[rank]!)} ${blitzBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
color: blitzBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
color: blitzBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
||||||
|
))
|
||||||
|
else TextSpan(text: "${readableIntDifference(blitz!.endContext!.score, closestAverageBlitz.value)} ${blitzBetterThanClosestAverage ? "better" : "worse"} than ${closestAverageBlitz.key!.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
|
color: blitzBetterThanClosestAverage ? Colors.greenAccent : Colors.redAccent
|
||||||
)),
|
)),
|
||||||
TextSpan(text: _dateFormat.format(blitz!.timestamp!)),
|
TextSpan(text: _dateFormat.format(blitz!.timestamp!)),
|
||||||
if (blitz!.rank != null) const TextSpan(text: " • "),
|
if (blitz!.rank != null) const TextSpan(text: " • "),
|
||||||
|
@ -1151,11 +1180,14 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
children: [
|
children: [
|
||||||
StatCellNum(playerStat: blitz!.endContext!.level, playerStatLabel: t.statCellNum.level, isScreenBig: true, higherIsBetter: true),
|
StatCellNum(playerStat: blitz!.endContext!.level, playerStatLabel: t.statCellNum.level, isScreenBig: true, higherIsBetter: true, smallDecimal: false),
|
||||||
StatCellNum(playerStat: blitz!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: true, higherIsBetter: true),
|
StatCellNum(playerStat: blitz!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: true, higherIsBetter: true, smallDecimal: false),
|
||||||
StatCellNum(playerStat: blitz!.endContext!.spp, playerStatLabel: t.statCellNum.spp, fractionDigits: 2, isScreenBig: true, higherIsBetter: true,)
|
StatCellNum(playerStat: blitz!.endContext!.spp, playerStatLabel: t.statCellNum.spp, fractionDigits: 2, isScreenBig: true, higherIsBetter: true)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (blitz != null) FinesseThingy(blitz?.endContext?.finesse, blitz?.endContext?.finessePercentage),
|
||||||
|
if (blitz != null) LineclearsThingy(blitz!.endContext!.clears, blitz!.endContext!.lines, blitz!.endContext!.holds, blitz!.endContext!.tSpins),
|
||||||
|
if (blitz != null) Text("${blitz!.endContext!.piecesPlaced} P • ${blitz!.endContext!.inputs} KP • ${f2.format(blitz!.endContext!.kpp)} KpP • ${f2.format(blitz!.endContext!.kps)} KpS")
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
@ -1170,6 +1202,15 @@ class _RecordThingy extends StatelessWidget {
|
||||||
/// Widget that displays data from [record]
|
/// Widget that displays data from [record]
|
||||||
const _RecordThingy({required this.record, this.rank});
|
const _RecordThingy({required this.record, this.rank});
|
||||||
|
|
||||||
|
Color getColorOfRank(int rank){
|
||||||
|
if (rank == 1) return Colors.yellowAccent;
|
||||||
|
if (rank == 2) return Colors.blueGrey;
|
||||||
|
if (rank == 3) return Colors.brown[400]!;
|
||||||
|
if (rank <= 9) return Colors.blueAccent;
|
||||||
|
if (rank <= 99) return Colors.greenAccent;
|
||||||
|
return Colors.grey;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (record == null) return Center(child: Text(t.noRecord, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)));
|
if (record == null) return Center(child: Text(t.noRecord, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)));
|
||||||
|
@ -1186,219 +1227,89 @@ class _RecordThingy extends StatelessWidget {
|
||||||
closestAverageBlitz = blitzAverages.entries.singleWhere((element) => element.value == blitzAverages.values.reduce((a, b) => (a-record!.endContext!.score).abs() < (b -record!.endContext!.score).abs() ? a : b));
|
closestAverageBlitz = blitzAverages.entries.singleWhere((element) => element.value == blitzAverages.values.reduce((a, b) => (a-record!.endContext!.score).abs() < (b -record!.endContext!.score).abs() ? a : b));
|
||||||
blitzBetterThanClosestAverage = record!.endContext!.score > closestAverageBlitz.value;
|
blitzBetterThanClosestAverage = record!.endContext!.score > closestAverageBlitz.value;
|
||||||
}
|
}
|
||||||
return LayoutBuilder(builder: (context, constraints) {
|
|
||||||
bool bigScreen = constraints.maxWidth > 768;
|
return LayoutBuilder(
|
||||||
return ListView.builder(
|
builder: (context, constraints) {
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
bool bigScreen = constraints.maxWidth > 768;
|
||||||
itemCount: 1,
|
return SingleChildScrollView(
|
||||||
itemBuilder: (BuildContext context, int index) {
|
child: Padding(
|
||||||
return Column(
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// show mode title
|
|
||||||
if (record!.stream.contains("40l")) Text(t.sprint, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28))
|
|
||||||
else if (record!.stream.contains("blitz")) Text(t.blitz, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
|
||||||
|
|
||||||
// show main metric
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
textBaseline: TextBaseline.alphabetic,
|
|
||||||
children: [
|
children: [
|
||||||
// Show grade based on closest rank average
|
if (record!.stream.contains("40l")) Padding(padding: EdgeInsets.only(right: 8.0),
|
||||||
if (record!.stream.contains("40l")) Image.asset("res/tetrio_tl_alpha_ranks/${closestAverageSprint.key}.png", height: 48)
|
child: Image.asset("res/tetrio_tl_alpha_ranks/${closestAverageSprint.key}.png", height: 96)
|
||||||
else if (record!.stream.contains("blitz")) Image.asset("res/tetrio_tl_alpha_ranks/${closestAverageBlitz.key}.png", height: 48),
|
),
|
||||||
|
if (record!.stream.contains("blitz")) Padding(padding: EdgeInsets.only(right: 8.0),
|
||||||
// Show result
|
child: Image.asset("res/tetrio_tl_alpha_ranks/${closestAverageBlitz.key}.png", height: 96)
|
||||||
if (record!.stream.contains("40l")) Text(get40lTime(record!.endContext!.finalTime.inMicroseconds), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28))
|
),
|
||||||
else if (record!.stream.contains("blitz")) Text(NumberFormat.decimalPattern().format(record!.endContext!.score), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (record!.stream.contains("40l")) Text(t.sprint, style: TextStyle(height: 0.1, fontFamily: "Eurostile Round Extended", fontSize: 18)),
|
||||||
|
if (record!.stream.contains("blitz")) Text(t.blitz, style: TextStyle(height: 0.1, fontFamily: "Eurostile Round Extended", fontSize: 18)),
|
||||||
|
RichText(text: TextSpan(
|
||||||
|
text: record!.stream.contains("40l") ? get40lTime(record!.endContext!.finalTime.inMicroseconds) : NumberFormat.decimalPattern().format(record!.endContext!.score),
|
||||||
|
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 36 : 32, fontWeight: FontWeight.w500, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RichText(text: TextSpan(
|
||||||
|
text: "",
|
||||||
|
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, color: Colors.grey),
|
||||||
|
children: [
|
||||||
|
if (record!.stream.contains("40l") && (rank != null && rank != "z")) TextSpan(text: "${readableTimeDifference(record!.endContext!.finalTime, sprintAverages[rank]!)} ${sprintBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
|
color: sprintBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
||||||
|
))
|
||||||
|
else if (record!.stream.contains("40l") && (rank == null || rank == "z")) TextSpan(text: "${readableTimeDifference(record!.endContext!.finalTime, closestAverageSprint.value)} ${sprintBetterThanClosestAverage ? "better" : "worse"} than ${closestAverageSprint.key.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
|
color: sprintBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
||||||
|
))
|
||||||
|
else if (record!.stream.contains("blitz") && (rank != null && rank != "z")) TextSpan(text: "${readableIntDifference(record!.endContext!.score, blitzAverages[rank]!)} ${blitzBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
|
color: blitzBetterThanRankAverage??false ? Colors.greenAccent : Colors.redAccent
|
||||||
|
))
|
||||||
|
else if (record!.stream.contains("blitz") && (rank == null || rank == "z")) TextSpan(text: "${readableIntDifference(record!.endContext!.score, closestAverageBlitz.value)} ${blitzBetterThanClosestAverage ? "better" : "worse"} than ${closestAverageBlitz.key!.toUpperCase()} rank average\n", style: TextStyle(
|
||||||
|
color: blitzBetterThanClosestAverage ? Colors.greenAccent : Colors.redAccent
|
||||||
|
)),
|
||||||
|
if (record!.rank != null) TextSpan(text: "№${record!.rank}", style: TextStyle(color: getColorOfRank(record!.rank!))),
|
||||||
|
if (record!.rank != null) const TextSpan(text: " • "),
|
||||||
|
TextSpan(text: _dateFormat.format(record!.timestamp!)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (record!.stream.contains("40l")) Wrap(
|
||||||
// Show difference between rank average
|
alignment: WrapAlignment.spaceBetween,
|
||||||
if (record!.stream.contains("40l") && (rank != null && rank != "z")) Text(
|
spacing: 20,
|
||||||
"${readableTimeDifference(record!.endContext!.finalTime, sprintAverages[rank]!)} ${sprintBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: sprintBetterThanRankAverage??false ?
|
|
||||||
Colors.greenAccent :
|
|
||||||
Colors.redAccent
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else if (record!.stream.contains("40l") && (rank == null || rank == "z")) Text(
|
|
||||||
"${readableTimeDifference(record!.endContext!.finalTime, closestAverageSprint.value)} ${sprintBetterThanClosestAverage ? "better" : "worse"} than ${closestAverageSprint.key!.toUpperCase()} rank average",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: sprintBetterThanClosestAverage ?
|
|
||||||
Colors.greenAccent :
|
|
||||||
Colors.redAccent
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else if (record!.stream.contains("blitz") && (rank != null && rank != "z")) Text(
|
|
||||||
"${readableIntDifference(record!.endContext!.score, blitzAverages[rank]!)} ${blitzBetterThanRankAverage??false ? "better" : "worse"} than ${rank!.toUpperCase()} rank average",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: blitzBetterThanRankAverage??false ?
|
|
||||||
Colors.greenAccent :
|
|
||||||
Colors.redAccent
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else if (record!.stream.contains("blitz") && (rank == null || rank == "z")) Text(
|
|
||||||
"${readableIntDifference(record!.endContext!.score, closestAverageBlitz.value)} ${blitzBetterThanClosestAverage ? "better" : "worse"} than ${closestAverageBlitz.key!.toUpperCase()} rank average",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: blitzBetterThanClosestAverage ?
|
|
||||||
Colors.greenAccent :
|
|
||||||
Colors.redAccent
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
// Show rank if presented
|
|
||||||
if (record!.rank != null) StatCellNum(playerStat: record!.rank!, playerStatLabel: "Leaderboard Placement", isScreenBig: bigScreen, higherIsBetter: false),
|
|
||||||
|
|
||||||
// Show when this record was obtained
|
|
||||||
Text(t.obtainDate(date: _dateFormat.format(record!.timestamp!)), textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 16)),
|
|
||||||
|
|
||||||
// Show metrics
|
|
||||||
Padding(padding: const EdgeInsets.fromLTRB(0, 48, 0, 48),
|
|
||||||
child: Wrap(
|
|
||||||
direction: Axis.horizontal,
|
|
||||||
alignment: WrapAlignment.spaceAround,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
|
||||||
clipBehavior: Clip.hardEdge,
|
|
||||||
spacing: 25,
|
|
||||||
children: [
|
children: [
|
||||||
if (record!.stream.contains("blitz")) StatCellNum(playerStat: record!.endContext!.level, playerStatLabel: t.statCellNum.level, isScreenBig: bigScreen, higherIsBetter: true),
|
StatCellNum(playerStat: record!.endContext!.piecesPlaced, playerStatLabel: t.statCellNum.pieces, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: false),
|
||||||
if (record!.stream.contains("blitz")) StatCellNum(playerStat: record!.endContext!.spp, playerStatLabel: t.statCellNum.spp, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true),
|
StatCellNum(playerStat: record!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: false),
|
||||||
StatCellNum(playerStat: record!.endContext!.piecesPlaced, playerStatLabel: t.statCellNum.pieces, isScreenBig: bigScreen, higherIsBetter: true),
|
StatCellNum(playerStat: record!.endContext!.kpp, playerStatLabel: t.statCellNum.kpp, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: false),
|
||||||
StatCellNum(playerStat: record!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true),
|
|
||||||
if (record!.endContext!.finesse != null) StatCellNum(playerStat: record!.endContext!.finesse!.faults, playerStatLabel: t.statCellNum.finesseFaults, isScreenBig: bigScreen, higherIsBetter: false),
|
|
||||||
if (record!.endContext!.finesse != null) StatCellNum(playerStat: record!.endContext!.finessePercentage * 100, playerStatLabel: t.statCellNum.finessePercentage, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true),
|
|
||||||
StatCellNum(playerStat: record!.endContext!.inputs, playerStatLabel: t.statCellNum.keys, isScreenBig: bigScreen, higherIsBetter: false),
|
|
||||||
StatCellNum(playerStat: record!.endContext!.kpp, playerStatLabel: t.statCellNum.kpp, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: false),
|
|
||||||
StatCellNum(playerStat: record!.endContext!.kps, playerStatLabel: t.statCellNum.kps, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true,),
|
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
if (record!.stream.contains("blitz")) Wrap(
|
||||||
// List of actions
|
alignment: WrapAlignment.spaceBetween,
|
||||||
Padding(padding: const EdgeInsets.fromLTRB(0, 16, 0, 48),
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
child: Container(width: bigScreen ? MediaQuery.of(context).size.width * 0.4 : MediaQuery.of(context).size.width * 0.85,
|
spacing: 20,
|
||||||
constraints: BoxConstraints(maxWidth: 452),
|
children: [
|
||||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start,
|
StatCellNum(playerStat: record!.endContext!.level, playerStatLabel: t.statCellNum.level, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: false),
|
||||||
children: [
|
StatCellNum(playerStat: record!.endContext!.pps, playerStatLabel: t.statCellNum.pps, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true, smallDecimal: false),
|
||||||
Row(
|
StatCellNum(playerStat: record!.endContext!.spp, playerStatLabel: t.statCellNum.spp, fractionDigits: 2, isScreenBig: bigScreen, higherIsBetter: true)
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
],
|
||||||
children: [
|
|
||||||
Text("${t.numOfGameActions.pc}:", style: const TextStyle(fontSize: 24)),
|
|
||||||
Text(record!.endContext!.clears.allClears.toString(), style: const TextStyle(fontSize: 24)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text("${t.numOfGameActions.hold}:", style: const TextStyle(fontSize: 24)),
|
|
||||||
Text(record!.endContext!.holds.toString(), style: const TextStyle(fontSize: 24)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text("${t.numOfGameActions.tspinsTotal}:", style: const TextStyle(fontSize: 24)),
|
|
||||||
Text(record!.endContext!.tSpins.toString(), style: const TextStyle(fontSize: 24)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin zero:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinZeros.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin singles:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinSingles.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin doubles:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinDoubles.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin triples:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinTriples.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin mini zero:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinMiniZeros.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin mini singles:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinMiniSingles.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - T-spin mini doubles:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.tSpinMiniDoubles.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text("${t.numOfGameActions.lineClears}:", style: const TextStyle(fontSize: 24)),
|
|
||||||
Text(record!.endContext!.lines.toString(), style: const TextStyle(fontSize: 24)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - Singles:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.singles.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - Doubles:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.doubles.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - Triples:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.triples.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(" - Quads:", style: TextStyle(fontSize: 18)),
|
|
||||||
Text(record!.endContext!.clears.quads.toString(), style: const TextStyle(fontSize: 18)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
FinesseThingy(record?.endContext?.finesse, record?.endContext?.finessePercentage),
|
||||||
|
LineclearsThingy(record!.endContext!.clears, record!.endContext!.lines, record!.endContext!.holds, record!.endContext!.tSpins),
|
||||||
|
if (record!.stream.contains("40l")) Text("${record!.endContext!.inputs} KP • ${f2.format(record!.endContext!.kps)} KpS"),
|
||||||
|
if (record!.stream.contains("blitz")) Text("${record!.endContext!.piecesPlaced} P • ${record!.endContext!.inputs} KP • ${f2.format(record!.endContext!.kpp)} KpP • ${f2.format(record!.endContext!.kps)} KpS")
|
||||||
]
|
]
|
||||||
);
|
),
|
||||||
});
|
),
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
|
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||||
|
import 'package:tetra_stats/utils/text_shadow.dart';
|
||||||
|
|
||||||
|
class FinesseThingy extends StatelessWidget{
|
||||||
|
final Finesse? finesse;
|
||||||
|
final double? finessePercentage;
|
||||||
|
|
||||||
|
const FinesseThingy(this.finesse, this.finessePercentage, {super.key});
|
||||||
|
|
||||||
|
Color getFinesseColor(){
|
||||||
|
if (finesse == null) return Colors.grey;
|
||||||
|
if (finesse!.faults == 0) return Colors.purpleAccent;
|
||||||
|
if (finessePercentage! > 0.4) return Colors.white;
|
||||||
|
else return Colors.redAccent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
alignment: AlignmentDirectional.bottomStart,
|
||||||
|
children: [
|
||||||
|
Text("f", style: TextStyle(
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
fontSize: 65,
|
||||||
|
height: 1.2,
|
||||||
|
)),
|
||||||
|
Positioned(child: Text("inesse", style: TextStyle(fontFamily: "Eurostile Round Extended")), left: 25, top: 20),
|
||||||
|
Positioned(
|
||||||
|
child: Text("${finesse != null ? finesse!.faults : "---"}F", style: TextStyle(
|
||||||
|
color: getFinesseColor()
|
||||||
|
)), right: 0, top: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10.0),
|
||||||
|
child: Text("${finesse != null ? f2.format(finessePercentage! * 100) : "---.--"}%", style: TextStyle(
|
||||||
|
shadows: textShadow,
|
||||||
|
fontFamily: "Eurostile Round Extended",
|
||||||
|
fontSize: 36,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: getFinesseColor()
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
|
import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
|
|
||||||
|
class LineclearsThingy extends StatelessWidget{
|
||||||
|
final Clears clears;
|
||||||
|
final int lines;
|
||||||
|
final int holds;
|
||||||
|
final int tSpins;
|
||||||
|
|
||||||
|
const LineclearsThingy(this.clears, this.lines, this.holds, this.tSpins, {super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Wrap(
|
||||||
|
spacing: 20,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 150,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(t.numOfGameActions.lineClears(n: lines), style: TextStyle(color: Colors.white, fontFamily: "Eurostile Round Extended")),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Quads"), Text(clears.quads.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Triples"), Text(clears.triples.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Doubles"), Text(clears.doubles.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Singles"), Text(clears.singles.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("\n${t.numOfGameActions.pc}"), Text("\n${clears.allClears.toString()}")]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text(t.numOfGameActions.hold), Text(holds.toString())]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 150,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(t.numOfGameActions.tspinsTotal(n: tSpins), style: TextStyle(color: Colors.white, fontFamily: "Eurostile Round Extended")),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("T-spins triples"), Text(clears.tSpinTriples.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("T-spins doubles"), Text(clears.tSpinDoubles.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("T-spins singles"), Text(clears.tSpinSingles.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("T-spins zeros"), Text(clears.tSpinZeros.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Mini T-spins doubles"), Text(clears.tSpinMiniDoubles.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Mini T-spins singles"), Text(clears.tSpinMiniSingles.toString())]),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text("Mini T-spins zeros"), Text(clears.tSpinMiniZeros.toString())]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -308,7 +308,7 @@ class _TLThingyState extends State<TLThingy> {
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
text: intf.format(currentTl.estTr!.esttr.truncate()),
|
text: intf.format(currentTl.estTr!.esttr.truncate()),
|
||||||
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: FontWeight.w500),
|
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
|
||||||
children: [TextSpan(text: fractionfEstTR.format(currentTl.estTr!.esttr - currentTl.estTr!.esttr.truncate()).substring(1), style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))]
|
children: [TextSpan(text: fractionfEstTR.format(currentTl.estTr!.esttr - currentTl.estTr!.esttr.truncate()).substring(1), style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))]
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -334,7 +334,7 @@ class _TLThingyState extends State<TLThingy> {
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? intFDiff.format(currentTl.esttracc!.truncate()) : "---",
|
text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? intFDiff.format(currentTl.esttracc!.truncate()) : "---",
|
||||||
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 36, fontWeight: FontWeight.w500),
|
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? fractionfEstTRAcc.format(currentTl.esttracc!.isNegative ? 1 - (currentTl.esttracc! - currentTl.esttracc!.truncate()) : (currentTl.esttracc! - currentTl.esttracc!.truncate())).substring(1) : ".---", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))
|
TextSpan(text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? fractionfEstTRAcc.format(currentTl.esttracc!.isNegative ? 1 - (currentTl.esttracc! - currentTl.esttracc!.truncate()) : (currentTl.esttracc! - currentTl.esttracc!.truncate())).substring(1) : ".---", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))
|
||||||
]
|
]
|
||||||
|
|
|
@ -238,8 +238,30 @@
|
||||||
"numOfGameActions":{
|
"numOfGameActions":{
|
||||||
"pc": "All Clears",
|
"pc": "All Clears",
|
||||||
"hold": "Holds",
|
"hold": "Holds",
|
||||||
"tspinsTotal": "T-spins total",
|
"inputs": {
|
||||||
"lineClears": "Line clears"
|
"zero": "$n key presses",
|
||||||
|
"one": "$n key press",
|
||||||
|
"two": "$n key presses",
|
||||||
|
"few": "$n key presses",
|
||||||
|
"many": "$n key presses",
|
||||||
|
"other": "$n key presses"
|
||||||
|
},
|
||||||
|
"tspinsTotal": {
|
||||||
|
"zero": "$n T-spins total",
|
||||||
|
"one": "$n T-spin total",
|
||||||
|
"two": "$n T-spins total",
|
||||||
|
"few": "$n T-spins total",
|
||||||
|
"many": "$n T-spins total",
|
||||||
|
"other": "$n T-spins total"
|
||||||
|
},
|
||||||
|
"lineClears": {
|
||||||
|
"zero": "$n lines cleared",
|
||||||
|
"one": "$n line cleared",
|
||||||
|
"two": "$n lines cleared",
|
||||||
|
"few": "$n lines cleared",
|
||||||
|
"many": "$n lines cleared",
|
||||||
|
"other": "$n lines cleared"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"popupActions":{
|
"popupActions":{
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
|
|
|
@ -238,8 +238,30 @@
|
||||||
"numOfGameActions":{
|
"numOfGameActions":{
|
||||||
"pc": "Все чисто",
|
"pc": "Все чисто",
|
||||||
"hold": "В запас",
|
"hold": "В запас",
|
||||||
"tspinsTotal": "T-spins всего",
|
"inputs": {
|
||||||
"lineClears": "Линий очищено"
|
"zero": "$n нажатий клавиш",
|
||||||
|
"one": "$n нажатие на клавишу",
|
||||||
|
"two": "$n нажатия на клавишы",
|
||||||
|
"few": "$n нажатия на клавишы",
|
||||||
|
"many": "$n нажатий на клавиш",
|
||||||
|
"other": "$n нажатий на клавиш"
|
||||||
|
},
|
||||||
|
"tspinsTotal": {
|
||||||
|
"zero": "$n T-спинов всего",
|
||||||
|
"one": "всего $n T-спин",
|
||||||
|
"two": "$n T-спина всего",
|
||||||
|
"few": "$n T-спина всего",
|
||||||
|
"many": "$n T-спинов всего",
|
||||||
|
"other": "$n T-спинов всего"
|
||||||
|
},
|
||||||
|
"lineClears": {
|
||||||
|
"zero": "$n линий очищено",
|
||||||
|
"one": "$n линия очищена",
|
||||||
|
"two": "$n линии очищено",
|
||||||
|
"few": "$n линии очищено",
|
||||||
|
"many": "$n линий очищено",
|
||||||
|
"other": "$n линий очищено"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"popupActions":{
|
"popupActions":{
|
||||||
"cancel": "Отменить",
|
"cancel": "Отменить",
|
||||||
|
|
Loading…
Reference in New Issue