Experimenting with layout
This commit is contained in:
parent
a726357f69
commit
8b95a32007
|
@ -38,6 +38,25 @@ const Map<String, double> rankCutoffs = {
|
|||
"z": -1,
|
||||
"": 0.5
|
||||
};
|
||||
const Map<String, double> rankTargets = {
|
||||
"x": 24008,
|
||||
"u": 23038,
|
||||
"ss": 21583,
|
||||
"s+": 20128,
|
||||
"s": 18673,
|
||||
"s-": 16975,
|
||||
"a+": 15035,
|
||||
"a": 13095,
|
||||
"a-": 11155,
|
||||
"b+": 9215,
|
||||
"b": 7275,
|
||||
"b-": 5335,
|
||||
"c+": 3880,
|
||||
"c": 2425,
|
||||
"c-": 1213,
|
||||
"d+": 606,
|
||||
"d": 0,
|
||||
};
|
||||
enum Stats {
|
||||
tr,
|
||||
glicko,
|
||||
|
@ -1883,6 +1902,26 @@ class TetrioPlayersLeaderboard {
|
|||
'z': getAverageOfRank("z")
|
||||
};
|
||||
|
||||
Map<String, double> get cutoffs => {
|
||||
'x': getAverageOfRank("x")[1]["toEnterTR"],
|
||||
'u': getAverageOfRank("u")[1]["toEnterTR"],
|
||||
'ss': getAverageOfRank("ss")[1]["toEnterTR"],
|
||||
's+': getAverageOfRank("s+")[1]["toEnterTR"],
|
||||
's': getAverageOfRank("s")[1]["toEnterTR"],
|
||||
's-': getAverageOfRank("s-")[1]["toEnterTR"],
|
||||
'a+': getAverageOfRank("a+")[1]["toEnterTR"],
|
||||
'a': getAverageOfRank("a")[1]["toEnterTR"],
|
||||
'a-': getAverageOfRank("a-")[1]["toEnterTR"],
|
||||
'b+': getAverageOfRank("b+")[1]["toEnterTR"],
|
||||
'b': getAverageOfRank("b")[1]["toEnterTR"],
|
||||
'b-': getAverageOfRank("b-")[1]["toEnterTR"],
|
||||
'c+': getAverageOfRank("c+")[1]["toEnterTR"],
|
||||
'c': getAverageOfRank("c")[1]["toEnterTR"],
|
||||
'c-': getAverageOfRank("c-")[1]["toEnterTR"],
|
||||
'd+': getAverageOfRank("d+")[1]["toEnterTR"],
|
||||
'd': getAverageOfRank("d")[1]["toEnterTR"]
|
||||
};
|
||||
|
||||
TetrioPlayersLeaderboard.fromJson(List<dynamic> json, String t, DateTime ts) {
|
||||
type = t;
|
||||
timestamp = ts;
|
||||
|
|
|
@ -728,6 +728,14 @@ class TetrioService extends DB {
|
|||
return matches;
|
||||
}
|
||||
|
||||
/// Gets and returns an amount of stored Tetra League mathes between [ourPlayerID] and [enemyPlayerID].
|
||||
Future<int> getNumberOfTLMatchesBetweenPlayers(String ourPlayerID, String enemyPlayerID) async {
|
||||
await ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
final results = await db.rawQuery("SELECT COUNT(*) from tetrioAlphaLeagueMathces WHERE (player1id = $ourPlayerID AND player2id = $enemyPlayerID) OR (player1id = $enemyPlayerID AND player2id = $ourPlayerID)");
|
||||
return results.first.values.first as int;
|
||||
}
|
||||
|
||||
/// Deletes match and stats of that match with given [matchID] from local DB. Throws an exception if fails.
|
||||
Future<void> deleteTLMatch(String matchID) async {
|
||||
await ensureDbIsOpen();
|
||||
|
|
|
@ -88,6 +88,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
final bodyGlobalKey = GlobalKey();
|
||||
bool _showSearchBar = false;
|
||||
late TabController _tabController;
|
||||
late TabController _wideScreenTabController;
|
||||
late bool fixedScroll;
|
||||
|
||||
@override
|
||||
|
@ -95,6 +96,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
initDB();
|
||||
_scrollController = ScrollController();
|
||||
_tabController = TabController(length: 6, vsync: this);
|
||||
_wideScreenTabController = TabController(length: 4, vsync: this);
|
||||
|
||||
// We need to show something
|
||||
if (widget.player != null){ // if we have user input,
|
||||
|
@ -279,12 +281,12 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
||||
bool bigScreen = MediaQuery.of(context).size.width > 1024;
|
||||
return Scaffold(
|
||||
drawer: widget.player == null ? NavDrawer(changePlayer) : null, // Side menu hidden if player provided
|
||||
drawerEdgeDragWidth: MediaQuery.of(context).size.width * 0.2, // 20% of left side of the screen used of Drawer gesture
|
||||
appBar: AppBar(
|
||||
title: _showSearchBar ? SearchBox(onSubmit: changePlayer, bigScreen: bigScreen) : Text(widget.title, style: const TextStyle(shadows: textShadow)),
|
||||
title: _showSearchBar ? SearchBox(onSubmit: changePlayer, bigScreen: MediaQuery.of(context).size.width > 768) : Text(widget.title, style: const TextStyle(shadows: textShadow)),
|
||||
backgroundColor: Colors.black,
|
||||
actions: widget.player == null ? [ // search bar and PopupMenuButton hidden if player provided TODO: Subject to change
|
||||
_showSearchBar
|
||||
|
@ -374,8 +376,9 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
return notification.depth == 0;
|
||||
},
|
||||
child: NestedScrollView(
|
||||
controller: _scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: _scrollController,
|
||||
scrollBehavior: const MaterialScrollBehavior(),
|
||||
headerSliverBuilder: (context, value) {
|
||||
return [
|
||||
SliverToBoxAdapter(
|
||||
|
@ -386,10 +389,15 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
)),
|
||||
SliverToBoxAdapter(
|
||||
child: TabBar(
|
||||
controller: _tabController,
|
||||
controller: bigScreen ? _wideScreenTabController : _tabController,
|
||||
padding: const EdgeInsets.all(0.0),
|
||||
isScrollable: true,
|
||||
tabs: [
|
||||
tabs: bigScreen ? [
|
||||
Tab(text: t.tetraLeague,),
|
||||
Tab(text: t.history),
|
||||
Tab(text: "${t.sprint} & ${t.blitz}"),
|
||||
Tab(text: t.other),
|
||||
] : [
|
||||
Tab(text: t.tetraLeague),
|
||||
Tab(text: t.tlRecords),
|
||||
Tab(text: t.history),
|
||||
|
@ -402,8 +410,44 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
];
|
||||
},
|
||||
body: TabBarView(
|
||||
controller: _tabController,
|
||||
children: [
|
||||
controller: bigScreen ? _wideScreenTabController : _tabController,
|
||||
children: bigScreen ? [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width-450,
|
||||
constraints: BoxConstraints(maxWidth: 1024),
|
||||
child: TLThingy(
|
||||
tl: snapshot.data![0].tlSeason1,
|
||||
userID: snapshot.data![0].userId,
|
||||
states: snapshot.data![2],
|
||||
topTR: snapshot.data![7],
|
||||
bot: snapshot.data![0].role == "bot",
|
||||
guest: snapshot.data![0].role == "anon",
|
||||
lbPositions: meAmongEveryone
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 450,
|
||||
child: _TLRecords(userID: snapshot.data![0].userId, data: snapshot.data![3])
|
||||
),
|
||||
],),
|
||||
_History(states: snapshot.data![2], update: _justUpdate),
|
||||
Row(children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width/2,
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: _RecordThingy(record: snapshot.data![1]['sprint'], rank: snapshot.data![0].tlSeason1.percentileRank)
|
||||
),
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width/2,
|
||||
padding: EdgeInsets.only(left: 8),
|
||||
child: _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],)
|
||||
] : [
|
||||
TLThingy(
|
||||
tl: snapshot.data![0].tlSeason1,
|
||||
userID: snapshot.data![0].userId,
|
||||
|
@ -600,9 +644,10 @@ class _TLRecords extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (data.isEmpty) return Center(child: Text(t.noRecords, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)));
|
||||
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
||||
bool bigScreen = MediaQuery.of(context).size.width >= 768;
|
||||
return ListView.builder(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: ScrollController(),
|
||||
itemCount: data.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var accentColor = data[index].endContext.firstWhere((element) => element.userId == userID).success ? Colors.green : Colors.red;
|
||||
|
|
|
@ -27,7 +27,11 @@ class TLThingy extends StatefulWidget {
|
|||
final double? topTR;
|
||||
final PlayerLeaderboardPosition? lbPositions;
|
||||
final TetraLeagueAlpha? averages;
|
||||
const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.guest=false, this.topTR, this.lbPositions, this.averages});
|
||||
final double? thatRankCutoff;
|
||||
final double? thatRankTarget;
|
||||
final double? nextRankCutoff;
|
||||
final double? nextRankTarget;
|
||||
const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.guest=false, this.topTR, this.lbPositions, this.averages, this.nextRankCutoff = 25000, this.thatRankCutoff = 0, this.nextRankTarget = 25000, this.thatRankTarget = 0});
|
||||
|
||||
@override
|
||||
State<TLThingy> createState() => _TLThingyState();
|
||||
|
@ -55,7 +59,7 @@ class _TLThingyState extends State<TLThingy> {
|
|||
NumberFormat fractionfEstTRAcc = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 3)..maximumIntegerDigits = 0;
|
||||
if (currentTl.gamesPlayed == 0) return Center(child: Text(widget.guest ? t.anonTL : widget.bot ? t.botTL : t.neverPlayedTL, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28), textAlign: TextAlign.center,));
|
||||
return LayoutBuilder(builder: (context, constraints) {
|
||||
bool bigScreen = constraints.maxWidth > 768;
|
||||
bool bigScreen = constraints.maxWidth >= 768;
|
||||
return ListView.builder(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
itemCount: 1,
|
||||
|
@ -313,7 +317,9 @@ class _TLThingyState extends State<TLThingy> {
|
|||
color: oldTl!.estTr!.esttr > currentTl.estTr!.esttr ? Colors.redAccent : Colors.greenAccent
|
||||
),),
|
||||
if (oldTl?.estTr?.esttr != null && widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
||||
if (widget.lbPositions?.estTr != null) TextSpan(text: widget.lbPositions!.estTr!.position >= 1000 ? "Top ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "№${widget.lbPositions!.estTr!.position}")
|
||||
if (widget.lbPositions?.estTr != null) TextSpan(text: widget.lbPositions!.estTr!.position >= 1000 ? "Top ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "№${widget.lbPositions!.estTr!.position}"),
|
||||
if (widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
||||
TextSpan(text: "Glicko: ${f2.format(currentTl.estTr!.estglicko)}")
|
||||
]
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue