Experimenting with layout
This commit is contained in:
parent
a726357f69
commit
8b95a32007
|
@ -38,6 +38,25 @@ const Map<String, double> rankCutoffs = {
|
||||||
"z": -1,
|
"z": -1,
|
||||||
"": 0.5
|
"": 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 {
|
enum Stats {
|
||||||
tr,
|
tr,
|
||||||
glicko,
|
glicko,
|
||||||
|
@ -1883,6 +1902,26 @@ class TetrioPlayersLeaderboard {
|
||||||
'z': getAverageOfRank("z")
|
'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) {
|
TetrioPlayersLeaderboard.fromJson(List<dynamic> json, String t, DateTime ts) {
|
||||||
type = t;
|
type = t;
|
||||||
timestamp = ts;
|
timestamp = ts;
|
||||||
|
|
|
@ -728,6 +728,14 @@ class TetrioService extends DB {
|
||||||
return matches;
|
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.
|
/// Deletes match and stats of that match with given [matchID] from local DB. Throws an exception if fails.
|
||||||
Future<void> deleteTLMatch(String matchID) async {
|
Future<void> deleteTLMatch(String matchID) async {
|
||||||
await ensureDbIsOpen();
|
await ensureDbIsOpen();
|
||||||
|
|
|
@ -88,6 +88,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
final bodyGlobalKey = GlobalKey();
|
final bodyGlobalKey = GlobalKey();
|
||||||
bool _showSearchBar = false;
|
bool _showSearchBar = false;
|
||||||
late TabController _tabController;
|
late TabController _tabController;
|
||||||
|
late TabController _wideScreenTabController;
|
||||||
late bool fixedScroll;
|
late bool fixedScroll;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -95,6 +96,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
initDB();
|
initDB();
|
||||||
_scrollController = ScrollController();
|
_scrollController = ScrollController();
|
||||||
_tabController = TabController(length: 6, vsync: this);
|
_tabController = TabController(length: 6, vsync: this);
|
||||||
|
_wideScreenTabController = TabController(length: 4, vsync: this);
|
||||||
|
|
||||||
// We need to show something
|
// We need to show something
|
||||||
if (widget.player != null){ // if we have user input,
|
if (widget.player != null){ // if we have user input,
|
||||||
|
@ -279,12 +281,12 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final t = Translations.of(context);
|
final t = Translations.of(context);
|
||||||
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
bool bigScreen = MediaQuery.of(context).size.width > 1024;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
drawer: widget.player == null ? NavDrawer(changePlayer) : null, // Side menu hidden if player provided
|
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
|
drawerEdgeDragWidth: MediaQuery.of(context).size.width * 0.2, // 20% of left side of the screen used of Drawer gesture
|
||||||
appBar: AppBar(
|
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,
|
backgroundColor: Colors.black,
|
||||||
actions: widget.player == null ? [ // search bar and PopupMenuButton hidden if player provided TODO: Subject to change
|
actions: widget.player == null ? [ // search bar and PopupMenuButton hidden if player provided TODO: Subject to change
|
||||||
_showSearchBar
|
_showSearchBar
|
||||||
|
@ -374,8 +376,9 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
return notification.depth == 0;
|
return notification.depth == 0;
|
||||||
},
|
},
|
||||||
child: NestedScrollView(
|
child: NestedScrollView(
|
||||||
controller: _scrollController,
|
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
controller: _scrollController,
|
||||||
|
scrollBehavior: const MaterialScrollBehavior(),
|
||||||
headerSliverBuilder: (context, value) {
|
headerSliverBuilder: (context, value) {
|
||||||
return [
|
return [
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
|
@ -386,10 +389,15 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
)),
|
)),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: TabBar(
|
child: TabBar(
|
||||||
controller: _tabController,
|
controller: bigScreen ? _wideScreenTabController : _tabController,
|
||||||
padding: const EdgeInsets.all(0.0),
|
padding: const EdgeInsets.all(0.0),
|
||||||
isScrollable: true,
|
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.tetraLeague),
|
||||||
Tab(text: t.tlRecords),
|
Tab(text: t.tlRecords),
|
||||||
Tab(text: t.history),
|
Tab(text: t.history),
|
||||||
|
@ -402,8 +410,44 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
body: TabBarView(
|
body: TabBarView(
|
||||||
controller: _tabController,
|
controller: bigScreen ? _wideScreenTabController : _tabController,
|
||||||
|
children: bigScreen ? [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
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(
|
TLThingy(
|
||||||
tl: snapshot.data![0].tlSeason1,
|
tl: snapshot.data![0].tlSeason1,
|
||||||
userID: snapshot.data![0].userId,
|
userID: snapshot.data![0].userId,
|
||||||
|
@ -600,9 +644,10 @@ class _TLRecords extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (data.isEmpty) return Center(child: Text(t.noRecords, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)));
|
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(
|
return ListView.builder(
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
controller: ScrollController(),
|
||||||
itemCount: data.length,
|
itemCount: data.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
var accentColor = data[index].endContext.firstWhere((element) => element.userId == userID).success ? Colors.green : Colors.red;
|
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 double? topTR;
|
||||||
final PlayerLeaderboardPosition? lbPositions;
|
final PlayerLeaderboardPosition? lbPositions;
|
||||||
final TetraLeagueAlpha? averages;
|
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
|
@override
|
||||||
State<TLThingy> createState() => _TLThingyState();
|
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;
|
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,));
|
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) {
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
bool bigScreen = constraints.maxWidth > 768;
|
bool bigScreen = constraints.maxWidth >= 768;
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
physics: const ClampingScrollPhysics(),
|
physics: const ClampingScrollPhysics(),
|
||||||
itemCount: 1,
|
itemCount: 1,
|
||||||
|
@ -313,7 +317,9 @@ class _TLThingyState extends State<TLThingy> {
|
||||||
color: oldTl!.estTr!.esttr > currentTl.estTr!.esttr ? Colors.redAccent : Colors.greenAccent
|
color: oldTl!.estTr!.esttr > currentTl.estTr!.esttr ? Colors.redAccent : Colors.greenAccent
|
||||||
),),
|
),),
|
||||||
if (oldTl?.estTr?.esttr != null && widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
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