Raw version of adaptivity + Issue Forms for GitHub

This commit is contained in:
dan63047 2024-11-23 21:41:48 +03:00
parent bf72c4cee3
commit defcab65f8
14 changed files with 324 additions and 235 deletions

View File

@ -1,32 +0,0 @@
---
name: Bug report
about: Tell me what is wrong with app
title: "[BUG]"
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**How to reproduce**
What did you do to got it, something like:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Technical information**
- Platform [Windows, Linux or Android]
- App Version
- Screen size (if it's visual bug)
**Additional context**
Add any other context about the problem here.

67
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View File

@ -0,0 +1,67 @@
name: Bug Report
description: Tell me what is wrong with app by filling this form.
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: Please, make sure that your issue haven't been reported before!
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Describe the issue you are experiencing right now
placeholder: Tell us what you see!
value: "A bug happened!"
validations:
required: true
- type: textarea
id: reproducing
attributes:
label: How did that happened?
description: Describe in details what do do to get this issue
placeholder: "Steps to reproduce:" |
1. Go here
2. Click this
3. Do that
etc...
validations:
required: true
- type: textarea
id: expectations
attributes:
label: What did you expected?
description: What should have happened instead?
placeholder: There is supposed to be ... instead
- type: checkboxes
id: platform
attributes:
label: On which platform you encountered this issue?
description: Tick the ones, where this issue can be reproduced
options:
- Web (ts.dan63.by)
- Windows
- Linux
- Android
- Web-beta (tsbeta.dan63.by)
default: 0
validations:
required: true
- type: input
id: browsers
attributes:
label: What version of Tetra Stats did you used?
description: You can find that info in Information Center -> About Tetra Stats
placeholder: 2.0.0
- type: textarea
id: additional-info
attributes:
label: Have anything more to say about that issue?
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: My repo have [Code of Conduct](https://example.com), which means that you should behave well.
options:
- label: I agree to follow this project's Code of Conduct
required: true

1
.github/ISSUE_TEMPLATE/config.yaml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: What do you wanna see in the app
title: "[FEATURE]"
labels: enhancement
assignees: ''
---
**Is it related to a problem?**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Elaborate about your feature**
A clear and concise description of what you want to see.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,36 @@
name: Feature request
description: Tell me what you want to see in this app by filling this form.
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: If your request does exist or it's similar to existing one, it's better to support existing one issue!
- type: textarea
id: problem
attributes:
label: Is it related to a problem?
description: Is your feature solves some problem?
placeholder: I don't like how i can't see or do this or that
- type: textarea
id: feature
attributes:
label: Elaborate about your feature
description: Describe in details what you want to see
placeholder: A thing, that allows us to see or do that! It's small and fluffy (what?)
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional context
description: What makes you think that is a good idea, or maybe, where did you saw that feature
placeholder: MinoMuncher can do this and that and I think in could be a good addition to Tetra Stats
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: My repo have [Code of Conduct](https://example.com), which means that you should behave well.
options:
- label: I agree to follow this project's Code of Conduct
required: true

View File

@ -30,17 +30,20 @@ class AboutCard extends StatelessWidget{
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card(child: Column( return Card(child: Column(
children: [ children: [
Text(title, style: Theme.of(context).textTheme.titleSmall), Text(title, style: Theme.of(context).textTheme.titleSmall, textAlign: TextAlign.center),
Divider(), Divider(),
Text(value, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white)), Text(value, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white)),
if (undervalue != null) Text(undervalue!), if (undervalue != null) Text(undervalue!, textAlign: TextAlign.center),
Divider(), Divider(),
Padding( Padding(
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: RichText(text: TextSpan( child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, color: Colors.grey, height: 0.6), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, color: Colors.grey, height: 0.6),
children: endvalue children: endvalue
)), )
),
) )
], ],
)); ));
@ -80,6 +83,7 @@ class AboutState extends State<AboutView> {
), ),
backgroundColor: Colors.black, backgroundColor: Colors.black,
body: SafeArea( body: SafeArea(
child: SingleChildScrollView(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -87,38 +91,61 @@ class AboutState extends State<AboutView> {
padding: const EdgeInsets.fromLTRB(0.0, 6.0, 0.0, 18.0), padding: const EdgeInsets.fromLTRB(0.0, 6.0, 0.0, 18.0),
child: Text("About Tetra Stats", style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center), child: Text("About Tetra Stats", style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center),
))), ))),
Row( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Card(child: Column(
flex: 2,
child: Card(child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Padding( Center(
child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Container(
constraints: BoxConstraints(maxWidth: 568.00),
child: Text( child: Text(
textAlign: TextAlign.center, textAlign: TextAlign.center,
"Tetra Stats is a service, that works with TETR.IO Tetra Channel API, providing data from it and calculating some addtitional metrics, based on this data. Service allows user to track their progress in Tetra League with \"Track\" function, which records every Tetra League change into local database (not automatically, you have to visit service from time to time), so these changes could be looked through graphs.\n\nBeanserver blaster is a part of a Tetra Stats, that decoupled into a serverside script. It provides full Tetra League leaderboard, allowing Tetra Stats to sort leaderboard by any metric and build scatter chart, that allows user to analyse Tetra League trends. It also provides history of Tetra League ranks cutoffs, which can be viewed by user via graph as well.\n\nThere is a plans to add replay analysis and tournaments history, so stay tuned!\n\nService is not associated with TETR.IO or osk in any capacity." "Tetra Stats is a service, that works with TETR.IO Tetra Channel API, providing data from it and calculating some addtitional metrics, based on this data. Service allows user to track their progress in Tetra League with \"Track\" function, which records every Tetra League change into local database (not automatically, you have to visit service from time to time), so these changes could be looked through graphs.\n\nBeanserver blaster is a part of a Tetra Stats, that decoupled into a serverside script. It provides full Tetra League leaderboard, allowing Tetra Stats to sort leaderboard by any metric and build scatter chart, that allows user to analyse Tetra League trends. It also provides history of Tetra League ranks cutoffs, which can be viewed by user via graph as well.\n\nThere is a plans to add replay analysis and tournaments history, so stay tuned!\n\nService is not associated with TETR.IO or osk in any capacity."
), ),
) ),
),
),
], ],
)), )),
), AboutCard("App Version", packageInfo.version, "Build ${packageInfo.buildNumber}", [
Expanded( TextSpan(text: "${packageInfo.appName} (${packageInfo.packageName}) • "),
child: Column( TextSpan(text: "GitHub Repo", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("github.com", "dan63047/TetraStats"));}),
TextSpan(text: ""),
TextSpan(text: "Submit an issue", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("github.com", "dan63047/TetraStats/issues/new/choose"));}),
]),
Card(child: Center(child: Padding(
padding: const EdgeInsets.fromLTRB(0.0, 6.0, 0.0, 18.0),
child: Text("Credits", style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center),
))),
Wrap(
direction: Axis.horizontal,
children: [ children: [
AboutCard("App Version", packageInfo.version, "Build ${packageInfo.buildNumber}", [TextSpan(text: "${packageInfo.appName} (${packageInfo.packageName}) • "), TextSpan(text: "GitHub Repo", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){ FractionallySizedBox(widthFactor: 1/((MediaQuery.of(context).size.width/600).ceil()), child: AboutCard("Autor & developer", "dan63", null, [
launchInBrowser(Uri.https("github.com", "dan63047/TetraStats")); TextSpan(text: "Support him!", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("dan63.by", "donate"));})
})]), ])),
AboutCard("Developed By", "dan63", null, [TextSpan(text: "Support him!", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("dan63.by", "donate"));})]), FractionallySizedBox(widthFactor: 1/((MediaQuery.of(context).size.width/600).ceil()), child: AboutCard("Provided formulas", "kerrmunism", null, [
//TextSpan(text: "Support him!", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("paypal.com", "paypalme/Kerrmunism"));})
])),
FractionallySizedBox(widthFactor: 1/((MediaQuery.of(context).size.width/600).ceil()), child: AboutCard("Provided S1 history", "p1nkl0bst3r", null, [
//TextSpan(text: "Support him!", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("paypal.com", "paypalme/Kerrmunism"));})
])),
FractionallySizedBox(widthFactor: 1/((MediaQuery.of(context).size.width/600).ceil()), child: AboutCard("Inoue (replay grabber)", "szy", null, [
//TextSpan(text: "Support him!", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("paypal.com", "paypalme/Kerrmunism"));})
])),
FractionallySizedBox(widthFactor: 1/((MediaQuery.of(context).size.width/600).ceil()), child: AboutCard("Simplfied Chinise locale", "neko_ab4093", null, [
//TextSpan(text: "Support him!", style: TextStyle(decoration: TextDecoration.underline, decorationColor: Colors.white70, decorationStyle: TextDecorationStyle.dotted, color: Theme.of(context).colorScheme.primary), recognizer: TapGestureRecognizer()..onTap = (){launchInBrowser(Uri.https("paypal.com", "paypalme/Kerrmunism"));})
])),
], ],
), ),
),
], ],
) )
], ],
),
)), )),
); );
} }

View File

@ -280,7 +280,7 @@ class _DestinationCutoffsState extends State<DestinationCutoffs> {
Padding( Padding(
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: TextButton(child: Text("View", textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500)), onPressed: () { child: TextButton(child: Text("View", textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500)), onPressed: () {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(maintainState: true,
builder: (context) => RankView(rank: rank, nextRankTR: rank == "x+" ? snapshot.data!.data["top1"]!.tr : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.tr, nextRankPercentile: rank == "x+" ? 0.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.percentile, nextRankTargetTR: rank == "x+" ? 25000.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.targetTr, totalPlayers: snapshot.data!.total, cutoffTetrio: snapshot.data!.data[rank]!), builder: (context) => RankView(rank: rank, nextRankTR: rank == "x+" ? snapshot.data!.data["top1"]!.tr : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.tr, nextRankPercentile: rank == "x+" ? 0.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.percentile, nextRankTargetTR: rank == "x+" ? 25000.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.targetTr, totalPlayers: snapshot.data!.total, cutoffTetrio: snapshot.data!.data[rank]!),
), ),
); );

View File

@ -287,7 +287,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
), ),
xValueMapper: (data, _) => data.x, xValueMapper: (data, _) => data.x,
yValueMapper: (data, _) => data.y, yValueMapper: (data, _) => data.y,
onPointTap: (point) => Navigator.push(context, MaterialPageRoute(builder: (context) => MainView(player: snapshot.data![point.pointIndex!].nickname), maintainState: false)), onPointTap: (point) => Navigator.push(context, MaterialPageRoute(builder: (context) => MainView(player: snapshot.data![point.pointIndex!].nickname))),
) )
], ],
); );

View File

@ -308,7 +308,7 @@ class _DestinationLeaderboardsState extends State<DestinationLeaderboards> {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => UserView(searchFor: snapshot.data![index].userId), builder: (context) => UserView(searchFor: snapshot.data![index].userId),
maintainState: false,
), ),
); );
}, },
@ -374,7 +374,7 @@ class _DestinationLeaderboardsState extends State<DestinationLeaderboards> {
child: rightSide(widget.constraints.maxWidth) child: rightSide(widget.constraints.maxWidth)
) )
), ),
maintainState: false,
), ),
); );
_currentLb = leaderboards.keys.elementAt(index); _currentLb = leaderboards.keys.elementAt(index);

View File

@ -173,7 +173,7 @@ class _DestinationSavedData extends State<DestinationSavedData> {
child: rightSide(widget.constraints.maxWidth, false) child: rightSide(widget.constraints.maxWidth, false)
) )
), ),
maintainState: false,
), ),
); );
}), }),

View File

@ -669,7 +669,7 @@ class _DestinationSettings extends State<DestinationSettings> with SingleTickerP
child: rightSide(widget.constraints.maxWidth, false) child: rightSide(widget.constraints.maxWidth, false)
) )
), ),
maintainState: false,
), ),
); );
}, },

View File

@ -30,6 +30,7 @@ int destination = 0;
// TODO: Redesign some widgets, so they could look nice on mobile view // TODO: Redesign some widgets, so they could look nice on mobile view
// - stats below TL progress bar & similar parts in other widgets // - stats below TL progress bar & similar parts in other widgets
// - APP and VS/APM gadget // - APP and VS/APM gadget
// - Badges widget needs some kind of scroll arrows for desktop mode (How is this related to this todo???)
Future<FetchResults> getData(String searchFor) async { Future<FetchResults> getData(String searchFor) async {
TetrioPlayer player; TetrioPlayer player;
@ -299,6 +300,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
elevation: 0, elevation: 0,
onPressed: () { onPressed: () {
_scaffoldKey.currentState!.openDrawer(); _scaffoldKey.currentState!.openDrawer();
_searchController.clear();
}, },
child: const Icon(Icons.search), child: const Icon(Icons.search),
), ),
@ -312,6 +314,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
elevation: 0, elevation: 0,
onPressed: () { onPressed: () {
_scaffoldKey.currentState!.openDrawer(); _scaffoldKey.currentState!.openDrawer();
_searchController.clear();
}, },
child: const Icon(Icons.search), child: const Icon(Icons.search),
), ),
@ -403,7 +406,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
SliverToBoxAdapter( SliverToBoxAdapter(
child: SearchBar( child: SearchBar(
controller: widget.controller, controller: widget.controller,
hintText: "Enter the username", hintText: "Username or ID",
hintStyle: const WidgetStatePropertyAll(TextStyle(color: Colors.grey)), hintStyle: const WidgetStatePropertyAll(TextStyle(color: Colors.grey)),
trailing: [ trailing: [
IconButton(onPressed: (){setState(() { IconButton(onPressed: (){setState(() {
@ -417,6 +420,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
Navigator.of(context).pop(); Navigator.of(context).pop();
}); });
}, },
autoFocus: true,
), ),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(

View File

@ -107,6 +107,144 @@ class _RankState extends State<RankView> {
); );
} }
Widget rightSide(double width, bool shortNames){
return SizedBox(
width: width,
child: FutureBuilder<List<dynamic>>(
future: getRanksAverages(widget.rank),
builder: (context, snapshot) {
switch (snapshot.connectionState){
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return const Center(child: CircularProgressIndicator());
case ConnectionState.done:
if (snapshot.hasError){ return FutureError(snapshot); }
if (snapshot.hasData){
return SingleChildScrollView(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: shortNames ? 140.0 : 200.0,
child: Card(
child: Column(
children: [
Text(shortNames ? "" : "Cheese Index", style: TextStyle(fontSize: 28, color: Colors.transparent)),
Divider(),
RankViewEntry(shortNames ? "TR" : "Tetra Rating", null, null),
RankViewEntry("Glicko", null, null, differentBG: true),
RankViewEntry("RD", null, null),
RankViewEntry("Glixare", null, null, differentBG: true),
RankViewEntry("S1 TR", null, null),
RankViewEntry(shortNames ? "GP" : "Games Played", null, null, differentBG: true),
RankViewEntry(shortNames ? "GW" : "Games Won", null, null),
RankViewEntry(shortNames ? "WR" : "Winrate", null, null, differentBG: true),
RankViewEntry(shortNames ? "APM" : "Attack Per Minute", null, null),
RankViewEntry(shortNames ? "PPS" : "Pieces Per Second", null, null, differentBG: true),
RankViewEntry(shortNames ? "VS" : "Versus Score", null, null),
RankViewEntry(shortNames ? "APP" : "Attack Per Piece", null, null, differentBG: true),
RankViewEntry("VS / APM", null, null),
RankViewEntry(shortNames ? "DS/P" : "Downstack Per Second", null, null, differentBG: true),
RankViewEntry(shortNames ? "DS/S" : "Downstack Per Piece", null, null),
RankViewEntry("APP + DS/P", null, null, differentBG: true),
RankViewEntry(shortNames ? "Cheese" : "Cheese Index", null, null),
RankViewEntry(shortNames ? "GbE" : "Garbage Efficiency", null, null, differentBG: true),
RankViewEntry(shortNames ? "wAPP" : "Weighted APP", null, null),
RankViewEntry("Area", null, null, differentBG: true),
RankViewEntry(shortNames ? "eTR" : "Estimated TR", null, null),
RankViewEntry(shortNames ? "±eTR" : "Est. TR Accuracy", null, null, differentBG: true),
RankViewEntry("Opener", null, null),
RankViewEntry("Plonk", null, null, differentBG: true),
RankViewEntry("Stride", null, null),
RankViewEntry(shortNames ? "Inf DS" : "Infinite Downstack", null, null, differentBG: true),
],
),
),
),
Expanded(
child: Card(
child: Column(
children: [
Text("Minimums", style: TextStyle(fontSize: 28)),
Divider(),
RankViewEntry("${f4.format(snapshot.data![1]["lowestTR"])}${shortNames ? "" : " TR"}", snapshot.data![1]["lowestTRnick"], snapshot.data![1]["lowestTRid"]),
RankViewEntry(f4.format(snapshot.data![1]["lowestGlicko"]), snapshot.data![1]["lowestGlickoNick"], snapshot.data![1]["lowestGlickoID"], differentBG: true),
RankViewEntry(f4.format(snapshot.data![1]["lowestRD"]), snapshot.data![1]["lowestRdNick"], snapshot.data![1]["lowestRdID"]),
RankViewEntry(f4.format(snapshot.data![1]["lowestGlixare"]), snapshot.data![1]["lowestGlixareNick"], snapshot.data![1]["lowestGlixareID"], differentBG: true),
RankViewEntry(f2.format(snapshot.data![1]["lowestS1tr"]), snapshot.data![1]["lowestS1trNick"], snapshot.data![1]["lowestS1trID"]),
RankViewEntry(intf.format(snapshot.data![1]["lowestGamesPlayed"]), snapshot.data![1]["lowestGamesPlayedNick"], snapshot.data![1]["lowestGamesPlayedID"], differentBG: true),
RankViewEntry(intf.format(snapshot.data![1]["lowestGamesWon"]), snapshot.data![1]["lowestGamesWonNick"], snapshot.data![1]["lowestGamesWonID"]),
RankViewEntry(percentage.format(snapshot.data![1]["lowestWinrate"]), snapshot.data![1]["lowestWinrateNick"], snapshot.data![1]["lowestWinrateID"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["lowestAPM"])}${shortNames ? "" : " APM"}", snapshot.data![1]["lowestAPMnick"], snapshot.data![1]["lowestAPMid"]),
RankViewEntry("${f2.format(snapshot.data![1]["lowestPPS"])}${shortNames ? "" : " PPS"}", snapshot.data![1]["lowestPPSnick"], snapshot.data![1]["lowestPPSid"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["lowestVS"])}${shortNames ? "" : " VS"}", snapshot.data![1]["lowestVSnick"], snapshot.data![1]["lowestVSid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestAPP"])}${shortNames ? "" : " APP"}", snapshot.data![1]["lowestAPPnick"], snapshot.data![1]["lowestAPPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestVSAPM"])}${shortNames ? "" : " VS/APM"}", snapshot.data![1]["lowestVSAPMnick"], snapshot.data![1]["lowestVSAPMid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestDSS"])}${shortNames ? "" : " DS/S"}", snapshot.data![1]["lowestDSSnick"], snapshot.data![1]["lowestDSSid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestDSP"])}${shortNames ? "" : " DS/P"}", snapshot.data![1]["lowestDSPnick"], snapshot.data![1]["lowestDSPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestAPPDSP"])}${shortNames ? "" : " APP+DS/P"}", snapshot.data![1]["lowestAPPDSPnick"], snapshot.data![1]["lowestAPPDSPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestCheese"])}${shortNames ? "" : " Cheese"}", snapshot.data![1]["lowestCheeseNick"], snapshot.data![1]["lowestCheeseID"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestGBE"])}${shortNames ? "" : " Gbe"}", snapshot.data![1]["lowestGBEnick"], snapshot.data![1]["lowestGBEid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestNyaAPP"])}${shortNames ? "" : " WAPP"}", snapshot.data![1]["lowestNyaAPPnick"], snapshot.data![1]["lowestNyaAPPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestArea"])}${shortNames ? "" : " Area"}", snapshot.data![1]["lowestAreaNick"], snapshot.data![1]["lowestAreaID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestEstTR"])}${shortNames ? "" : " eTR"}", snapshot.data![1]["lowestEstTRnick"], snapshot.data![1]["lowestEstTRid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestEstAcc"])}${shortNames ? "" : " ±eTR"}", snapshot.data![1]["lowestEstAccNick"], snapshot.data![1]["lowestEstAccID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestOpener"])}", snapshot.data![1]["lowestOpenerNick"], snapshot.data![1]["lowestOpenerID"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestPlonk"])}", snapshot.data![1]["lowestPlonkNick"], snapshot.data![1]["lowestPlonkID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestStride"])}", snapshot.data![1]["lowestStrideNick"], snapshot.data![1]["lowestStrideID"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestInfDS"])}", snapshot.data![1]["lowestInfDSnick"], snapshot.data![1]["lowestInfDSid"], differentBG: true)
],
),
),
),
Expanded(
child: Card(
child: Column(
children: [
Text("Maximums", style: TextStyle(fontSize: 28)),
Divider(),
RankViewEntry("${f4.format(snapshot.data![1]["highestTR"])}${shortNames ? "" : " TR"}", snapshot.data![1]["highestTRnick"], snapshot.data![1]["highestTRid"]),
RankViewEntry(f4.format(snapshot.data![1]["highestGlicko"]), snapshot.data![1]["highestGlickoNick"], snapshot.data![1]["highestGlickoID"], differentBG: true),
RankViewEntry(f4.format(snapshot.data![1]["highestRD"]), snapshot.data![1]["highestRdNick"], snapshot.data![1]["highestRdID"]),
RankViewEntry(f4.format(snapshot.data![1]["highestGlixare"]), snapshot.data![1]["highestGlixareNick"], snapshot.data![1]["highestGlixareID"], differentBG: true),
RankViewEntry(f2.format(snapshot.data![1]["highestS1tr"]), snapshot.data![1]["highestS1trNick"], snapshot.data![1]["highestS1trID"]),
RankViewEntry(intf.format(snapshot.data![1]["highestGamesPlayed"]), snapshot.data![1]["highestGamesPlayedNick"], snapshot.data![1]["highestGamesPlayedID"], differentBG: true),
RankViewEntry(intf.format(snapshot.data![1]["highestGamesWon"]), snapshot.data![1]["highestGamesWonNick"], snapshot.data![1]["highestGamesWonID"]),
RankViewEntry(percentage.format(snapshot.data![1]["highestWinrate"]), snapshot.data![1]["highestWinrateNick"], snapshot.data![1]["highestWinrateID"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["highestAPM"])}${shortNames ? "" : " APM"}", snapshot.data![1]["highestAPMnick"], snapshot.data![1]["highestAPMid"]),
RankViewEntry("${f2.format(snapshot.data![1]["highestPPS"])}${shortNames ? "" : " PPS"}", snapshot.data![1]["highestPPSnick"], snapshot.data![1]["highestPPSid"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["highestVS"])}${shortNames ? "" : " VS"}", snapshot.data![1]["highestVSnick"], snapshot.data![1]["highestVSid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestAPP"])}${shortNames ? "" : " APP"}", snapshot.data![1]["highestAPPnick"], snapshot.data![1]["highestAPPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestVSAPM"])}${shortNames ? "" : " VS/APM"}", snapshot.data![1]["highestVSAPMnick"], snapshot.data![1]["highestVSAPMid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestDSS"])}${shortNames ? "" : " DS/S"}", snapshot.data![1]["highestDSSnick"], snapshot.data![1]["highestDSSid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestDSP"])}${shortNames ? "" : " DS/P"}", snapshot.data![1]["highestDSPnick"], snapshot.data![1]["highestDSPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestAPPDSP"])}${shortNames ? "" : " APP+DS/P"}", snapshot.data![1]["highestAPPDSPnick"], snapshot.data![1]["highestAPPDSPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestCheese"])}${shortNames ? "" : " Cheese"}", snapshot.data![1]["highestCheeseNick"], snapshot.data![1]["highestCheeseID"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestGBE"])}${shortNames ? "" : " Gbe"}", snapshot.data![1]["highestGBEnick"], snapshot.data![1]["highestGBEid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestNyaAPP"])}${shortNames ? "" : " wAPP"}", snapshot.data![1]["highestNyaAPPnick"], snapshot.data![1]["highestNyaAPPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestArea"])}${shortNames ? "" : " Area"}", snapshot.data![1]["highestAreaNick"], snapshot.data![1]["highestAreaID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestEstTR"])}${shortNames ? "" : " eTR"}", snapshot.data![1]["highestEstTRnick"], snapshot.data![1]["highestEstTRid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestEstAcc"])}${shortNames ? "" : " ±eTR"}", snapshot.data![1]["highestEstAccNick"], snapshot.data![1]["highestEstAccID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestOpener"])}", snapshot.data![1]["highestOpenerNick"], snapshot.data![1]["highestOpenerID"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestPlonk"])}", snapshot.data![1]["highestPlonkNick"], snapshot.data![1]["highestPlonkID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestStride"])}", snapshot.data![1]["highestStrideNick"], snapshot.data![1]["highestStrideID"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestInfDS"])}", snapshot.data![1]["highestInfDSnick"], snapshot.data![1]["highestInfDSid"], differentBG: true)
],
),
),
)
],
),
);
}
}
return const Text("End of FutureBuilder<List>");
}
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double percentileGap = widget.cutoffTetrio.percentile - widget.nextRankPercentile; double percentileGap = widget.cutoffTetrio.percentile - widget.nextRankPercentile;
@ -126,7 +264,7 @@ class _RankState extends State<RankView> {
return Row( return Row(
children: [ children: [
SizedBox( SizedBox(
width: 350.0, width: constraints.maxWidth <= 768.0 ? constraints.maxWidth : 350.0,
height: constraints.maxHeight, height: constraints.maxHeight,
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
@ -252,7 +390,9 @@ class _RankState extends State<RankView> {
return Text("End of the FutureBuilder"); return Text("End of the FutureBuilder");
}, },
) )
else partOfTheWidget(null) else partOfTheWidget(null),
if (constraints.maxWidth <= 768.0) Divider(),
if (constraints.maxWidth <= 768.0) rightSide(constraints.maxWidth, true)
], ],
), ),
), ),
@ -261,141 +401,7 @@ class _RankState extends State<RankView> {
), ),
) )
), ),
SizedBox( if (constraints.maxWidth > 768.0) rightSide(constraints.maxWidth - 350, false)
width: constraints.maxWidth - 350,
child: FutureBuilder<List<dynamic>>(
future: getRanksAverages(widget.rank),
builder: (context, snapshot) {
switch (snapshot.connectionState){
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return const Center(child: CircularProgressIndicator());
case ConnectionState.done:
if (snapshot.hasError){ return FutureError(snapshot); }
if (snapshot.hasData){
return SingleChildScrollView(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 200.0,
child: Card(
child: Column(
children: [
Text("Cheese Index", style: TextStyle(fontSize: 28, color: Colors.transparent)),
Divider(),
RankViewEntry("Tetra Rating", null, null),
RankViewEntry("Glicko", null, null, differentBG: true),
RankViewEntry("RD", null, null),
RankViewEntry("Glixare", null, null, differentBG: true),
RankViewEntry("S1 TR", null, null),
RankViewEntry("Games Played", null, null, differentBG: true),
RankViewEntry("Games Won", null, null),
RankViewEntry("Winrate", null, null, differentBG: true),
RankViewEntry("Attack Per Minute", null, null),
RankViewEntry("Pieces Per Second", null, null, differentBG: true),
RankViewEntry("Versus Score", null, null),
RankViewEntry("Attack Per Piece", null, null, differentBG: true),
RankViewEntry("VS / APM", null, null),
RankViewEntry("Downstack Per Second", null, null, differentBG: true),
RankViewEntry("Downstack Per Piece", null, null),
RankViewEntry("APP + DS/P", null, null, differentBG: true),
RankViewEntry("Cheese Index", null, null),
RankViewEntry("Garbage Efficiency", null, null, differentBG: true),
RankViewEntry("Weighted APP", null, null),
RankViewEntry("Area", null, null, differentBG: true),
RankViewEntry("Estimated TR", null, null),
RankViewEntry("Est. TR Accuracy", null, null, differentBG: true),
RankViewEntry("Opener", null, null),
RankViewEntry("Plonk", null, null, differentBG: true),
RankViewEntry("Stride", null, null),
RankViewEntry("Infinite Downstack", null, null, differentBG: true),
],
),
),
),
Expanded(
child: Card(
child: Column(
children: [
Text("Minimums", style: TextStyle(fontSize: 28)),
Divider(),
RankViewEntry("${f4.format(snapshot.data![1]["lowestTR"])} TR", snapshot.data![1]["lowestTRnick"], snapshot.data![1]["lowestTRid"]),
RankViewEntry(f4.format(snapshot.data![1]["lowestGlicko"]), snapshot.data![1]["lowestGlickoNick"], snapshot.data![1]["lowestGlickoID"], differentBG: true),
RankViewEntry(f4.format(snapshot.data![1]["lowestRD"]), snapshot.data![1]["lowestRdNick"], snapshot.data![1]["lowestRdID"]),
RankViewEntry(f4.format(snapshot.data![1]["lowestGlixare"]), snapshot.data![1]["lowestGlixareNick"], snapshot.data![1]["lowestGlixareID"], differentBG: true),
RankViewEntry(f2.format(snapshot.data![1]["lowestS1tr"]), snapshot.data![1]["lowestS1trNick"], snapshot.data![1]["lowestS1trID"]),
RankViewEntry(intf.format(snapshot.data![1]["lowestGamesPlayed"]), snapshot.data![1]["lowestGamesPlayedNick"], snapshot.data![1]["lowestGamesPlayedID"], differentBG: true),
RankViewEntry(intf.format(snapshot.data![1]["lowestGamesWon"]), snapshot.data![1]["lowestGamesWonNick"], snapshot.data![1]["lowestGamesWonID"]),
RankViewEntry(percentage.format(snapshot.data![1]["lowestWinrate"]), snapshot.data![1]["lowestWinrateNick"], snapshot.data![1]["lowestWinrateID"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["lowestAPM"])} APM", snapshot.data![1]["lowestAPMnick"], snapshot.data![1]["lowestAPMid"]),
RankViewEntry("${f2.format(snapshot.data![1]["lowestPPS"])} PPS", snapshot.data![1]["lowestPPSnick"], snapshot.data![1]["lowestPPSid"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["lowestVS"])} VS", snapshot.data![1]["lowestVSnick"], snapshot.data![1]["lowestVSid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestAPP"])} APP", snapshot.data![1]["lowestAPPnick"], snapshot.data![1]["lowestAPPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestVSAPM"])} VS/APM", snapshot.data![1]["lowestVSAPMnick"], snapshot.data![1]["lowestVSAPMid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestDSS"])} DS/S", snapshot.data![1]["lowestDSSnick"], snapshot.data![1]["lowestDSSid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestDSP"])} DS/P", snapshot.data![1]["lowestDSPnick"], snapshot.data![1]["lowestDSPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestAPPDSP"])} APP+DS/P", snapshot.data![1]["lowestAPPDSPnick"], snapshot.data![1]["lowestAPPDSPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestCheese"])} Cheese", snapshot.data![1]["lowestCheeseNick"], snapshot.data![1]["lowestCheeseID"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestGBE"])} Gbe", snapshot.data![1]["lowestGBEnick"], snapshot.data![1]["lowestGBEid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestNyaAPP"])} wAPP", snapshot.data![1]["lowestNyaAPPnick"], snapshot.data![1]["lowestNyaAPPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestArea"])} Area", snapshot.data![1]["lowestAreaNick"], snapshot.data![1]["lowestAreaID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestEstTR"])} eTR", snapshot.data![1]["lowestEstTRnick"], snapshot.data![1]["lowestEstTRid"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestEstAcc"])} ±eTR", snapshot.data![1]["lowestEstAccNick"], snapshot.data![1]["lowestEstAccID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestOpener"])}", snapshot.data![1]["lowestOpenerNick"], snapshot.data![1]["lowestOpenerID"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestPlonk"])}", snapshot.data![1]["lowestPlonkNick"], snapshot.data![1]["lowestPlonkID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["lowestStride"])}", snapshot.data![1]["lowestStrideNick"], snapshot.data![1]["lowestStrideID"]),
RankViewEntry("${f4.format(snapshot.data![1]["lowestInfDS"])}", snapshot.data![1]["lowestInfDSnick"], snapshot.data![1]["lowestInfDSid"], differentBG: true)
],
),
),
),
Expanded(
child: Card(
child: Column(
children: [
Text("Maximums", style: TextStyle(fontSize: 28)),
Divider(),
RankViewEntry("${f4.format(snapshot.data![1]["highestTR"])} TR", snapshot.data![1]["highestTRnick"], snapshot.data![1]["highestTRid"]),
RankViewEntry(f4.format(snapshot.data![1]["highestGlicko"]), snapshot.data![1]["highestGlickoNick"], snapshot.data![1]["highestGlickoID"], differentBG: true),
RankViewEntry(f4.format(snapshot.data![1]["highestRD"]), snapshot.data![1]["highestRdNick"], snapshot.data![1]["highestRdID"]),
RankViewEntry(f4.format(snapshot.data![1]["highestGlixare"]), snapshot.data![1]["highestGlixareNick"], snapshot.data![1]["highestGlixareID"], differentBG: true),
RankViewEntry(f2.format(snapshot.data![1]["highestS1tr"]), snapshot.data![1]["highestS1trNick"], snapshot.data![1]["highestS1trID"]),
RankViewEntry(intf.format(snapshot.data![1]["highestGamesPlayed"]), snapshot.data![1]["highestGamesPlayedNick"], snapshot.data![1]["highestGamesPlayedID"], differentBG: true),
RankViewEntry(intf.format(snapshot.data![1]["highestGamesWon"]), snapshot.data![1]["highestGamesWonNick"], snapshot.data![1]["highestGamesWonID"]),
RankViewEntry(percentage.format(snapshot.data![1]["highestWinrate"]), snapshot.data![1]["highestWinrateNick"], snapshot.data![1]["highestWinrateID"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["highestAPM"])} APM", snapshot.data![1]["highestAPMnick"], snapshot.data![1]["highestAPMid"]),
RankViewEntry("${f2.format(snapshot.data![1]["highestPPS"])} PPS", snapshot.data![1]["highestPPSnick"], snapshot.data![1]["highestPPSid"], differentBG: true),
RankViewEntry("${f2.format(snapshot.data![1]["highestVS"])} VS", snapshot.data![1]["highestVSnick"], snapshot.data![1]["highestVSid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestAPP"])} APP", snapshot.data![1]["highestAPPnick"], snapshot.data![1]["highestAPPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestVSAPM"])} VS/APM", snapshot.data![1]["highestVSAPMnick"], snapshot.data![1]["highestVSAPMid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestDSS"])} DS/S", snapshot.data![1]["highestDSSnick"], snapshot.data![1]["highestDSSid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestDSP"])} DS/P", snapshot.data![1]["highestDSPnick"], snapshot.data![1]["highestDSPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestAPPDSP"])} APP+DS/P", snapshot.data![1]["highestAPPDSPnick"], snapshot.data![1]["highestAPPDSPid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestCheese"])} Cheese", snapshot.data![1]["highestCheeseNick"], snapshot.data![1]["highestCheeseID"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestGBE"])} Gbe", snapshot.data![1]["highestGBEnick"], snapshot.data![1]["highestGBEid"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestNyaAPP"])} wAPP", snapshot.data![1]["highestNyaAPPnick"], snapshot.data![1]["highestNyaAPPid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestArea"])} Area", snapshot.data![1]["highestAreaNick"], snapshot.data![1]["highestAreaID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestEstTR"])} eTR", snapshot.data![1]["highestEstTRnick"], snapshot.data![1]["highestEstTRid"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestEstAcc"])} ±eTR", snapshot.data![1]["highestEstAccNick"], snapshot.data![1]["highestEstAccID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestOpener"])}", snapshot.data![1]["highestOpenerNick"], snapshot.data![1]["highestOpenerID"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestPlonk"])}", snapshot.data![1]["highestPlonkNick"], snapshot.data![1]["highestPlonkID"], differentBG: true),
RankViewEntry("${f4.format(snapshot.data![1]["highestStride"])}", snapshot.data![1]["highestStrideNick"], snapshot.data![1]["highestStrideID"]),
RankViewEntry("${f4.format(snapshot.data![1]["highestInfDS"])}", snapshot.data![1]["highestInfDSnick"], snapshot.data![1]["highestInfDSid"], differentBG: true)
],
),
),
)
],
),
);
}
}
return const Text("End of FutureBuilder<List>");
}
),
)
], ],
); );
},), },),

View File

@ -2,7 +2,7 @@ name: tetra_stats
description: Track your and other player stats in TETR.IO description: Track your and other player stats in TETR.IO
publish_to: 'none' publish_to: 'none'
version: 1.6.12+38 version: 2.0.0-beta+339
environment: environment:
sdk: '>=3.0.0' sdk: '>=3.0.0'