okay that's better i think

This commit is contained in:
dan63047 2023-05-30 23:37:10 +03:00
parent a9964e7154
commit d0a7315955
2 changed files with 128 additions and 88 deletions

View File

@ -93,7 +93,7 @@ class TetrioPlayer {
distinguishment = json['distinguishment'] != null distinguishment = json['distinguishment'] != null
? Distinguishment.fromJson(json['distinguishment']) ? Distinguishment.fromJson(json['distinguishment'])
: null; : null;
friendCount = json['friend_count']; friendCount = json['friend_count'] != null ? json['friend_count'] : 0;
} }
Future<void> getRecords() async { Future<void> getRecords() async {
@ -570,7 +570,7 @@ class TetraLeagueAlpha {
glicko = json['glicko']?.toDouble(); glicko = json['glicko']?.toDouble();
rd = json['rd']?.toDouble(); rd = json['rd']?.toDouble();
rank = json['rank']; rank = json['rank'];
bestRank = json['bestrank']; bestRank = json['bestrank'].toString();
apm = json['apm']?.toDouble(); apm = json['apm']?.toDouble();
pps = json['pps']?.toDouble(); pps = json['pps']?.toDouble();
vs = json['vs']?.toDouble(); vs = json['vs']?.toDouble();

View File

@ -6,6 +6,12 @@ import 'package:tetra_stats/data_objects/tetrio.dart';
import 'package:tetra_stats/services/tetrio_crud.dart'; import 'package:tetra_stats/services/tetrio_crud.dart';
import 'package:tetra_stats/services/sqlite_db_controller.dart'; import 'package:tetra_stats/services/sqlite_db_controller.dart';
extension StringExtension on String {
String capitalize() {
return "${this[0].toUpperCase()}${this.substring(1).toLowerCase()}";
}
}
String _searchFor = ""; String _searchFor = "";
late Future<TetrioPlayer> me; late Future<TetrioPlayer> me;
DB db = DB(); DB db = DB();
@ -33,11 +39,13 @@ Future<TetrioPlayer> fetchTetrioPlayer(String user) async {
if (response.statusCode == 200) { if (response.statusCode == 200) {
// If the server did return a 200 OK response, // If the server did return a 200 OK response,
// then parse the JSON. // then parse the JSON.
return TetrioPlayer.fromJson( return jsonDecode(response.body)['success']
jsonDecode(response.body)['data']['user'], ? TetrioPlayer.fromJson(
DateTime.fromMillisecondsSinceEpoch( jsonDecode(response.body)['data']['user'],
jsonDecode(response.body)['cache']['cached_at'], DateTime.fromMillisecondsSinceEpoch(
isUtc: true)); jsonDecode(response.body)['cache']['cached_at'],
isUtc: true))
: throw Exception("User doesn't exist");
} else { } else {
// If the server did not return a 200 OK response, // If the server did not return a 200 OK response,
// then throw an exception. // then throw an exception.
@ -47,7 +55,6 @@ Future<TetrioPlayer> fetchTetrioPlayer(String user) async {
class _MainViewState extends State<MainView> { class _MainViewState extends State<MainView> {
bool _searchBoolean = false; bool _searchBoolean = false;
String _coverLink = "";
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -106,10 +113,6 @@ class _MainViewState extends State<MainView> {
), ),
) )
: _searchTextField(), : _searchTextField(),
flexibleSpace: Image.network(
_coverLink,
fit: BoxFit.cover,
),
backgroundColor: Colors.black, backgroundColor: Colors.black,
actions: [ actions: [
!_searchBoolean !_searchBoolean
@ -156,8 +159,6 @@ class _MainViewState extends State<MainView> {
future: me, future: me,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
_coverLink =
"https://tetr.io/user-content/banners/${snapshot.data!.userId}.jpg?rv=${snapshot.data!.bannerRevision}";
return ListView( return ListView(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
children: [ children: [
@ -276,14 +277,11 @@ class NavDrawer extends StatelessWidget {
class _UserThingy extends StatelessWidget { class _UserThingy extends StatelessWidget {
final TetrioPlayer player; final TetrioPlayer player;
const _UserThingy({Key? key, required this.player}) : super(key: key); _UserThingy({Key? key, required this.player}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) { return LayoutBuilder(builder: (context, constraints) {
final settings = context
.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
return Column( return Column(
children: [ children: [
Flex( Flex(
@ -291,13 +289,34 @@ class _UserThingy extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
ClipRRect( Stack(
borderRadius: BorderRadius.circular(1000), alignment: Alignment.topCenter,
child: Image.network( children: [
"https://tetr.io/user-content/avatars/${player.userId}.jpg?rv=${player.avatarRevision}", if (player.bannerRevision != null)
fit: BoxFit.fitHeight, Image.network(
height: 128, "https://tetr.io/user-content/banners/${player.userId}.jpg?rv=${player.bannerRevision}",
), fit: BoxFit.cover,
height: 240,
),
Container(
padding: EdgeInsets.fromLTRB(
0, player.bannerRevision != null ? 170 : 64, 0, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(1000),
child: Image.network(
"https://tetr.io/user-content/avatars/${player.userId}.jpg?rv=${player.avatarRevision}",
fit: BoxFit.fitHeight,
height: 128,
errorBuilder: (context, error, stackTrace) =>
Image.network(
"https://tetr.io/res/avatar.png",
fit: BoxFit.fitHeight,
height: 128,
),
),
),
),
],
), ),
Flexible( Flexible(
child: Column( child: Column(
@ -319,25 +338,66 @@ class _UserThingy extends StatelessWidget {
), ),
], ],
), ),
(player.role != "banned")
? Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
spacing: 25,
crossAxisAlignment: WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge, // hard WHAT???
children: [
_StatCellNum(
playerStat: player.level,
playerStatLabel: "Level",
snackBar:
"${player.xp.floor().toString()} XP, ${((player.level - player.level.floor()) * 100).toStringAsFixed(2)} % until next level",
),
if (player.gameTime >= Duration.zero)
_StatCellNum(
playerStat: (player.gameTime.inSeconds / 3600),
playerStatLabel: "Hours\nPlayed",
snackBar: player.gameTime.toString(),
),
if (player.gamesPlayed >= 0)
_StatCellNum(
playerStat: player.gamesPlayed,
playerStatLabel: "Games\nPlayed"),
if (player.gamesWon >= 0)
_StatCellNum(
playerStat: player.gamesWon,
playerStatLabel: "Games\nWon"),
if (player.friendCount > 0)
_StatCellNum(
playerStat: player.friendCount,
playerStatLabel: "Friends"),
],
)
: Text(
"BANNED",
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: "Eurostile Round Extended",
fontWeight: FontWeight.w900,
color: Colors.red,
fontSize: 60,
),
),
Wrap( Wrap(
direction: Axis.horizontal, direction: Axis.horizontal,
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
spacing: 25, spacing: 25,
crossAxisAlignment: WrapCrossAlignment.start, crossAxisAlignment: WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge, // hard WHAT??? clipBehavior: Clip.hardEdge,
children: [ children: [
_StatCellNum( Text(
playerStat: player.level, "${player.role.capitalize()} account ${player.registrationTime == null ? "that was from very beginning" : 'created ${player.registrationTime}'}",
playerStatLabel: "Level\n${player.xp.floor().toString()} XP"), style: const TextStyle(
_StatCellDuration( fontFamily: "Eurostile Round",
playerStat: player.gameTime, playerStatLabel: "Gametime"), color: Colors.white,
_StatCellNum( fontSize: 16,
playerStat: player.gamesPlayed, ))
playerStatLabel: "Games\nPlayed"),
_StatCellNum(
playerStat: player.gamesWon, playerStatLabel: "Games\nWon"),
], ],
) ),
], ],
); );
}); });
@ -345,72 +405,52 @@ class _UserThingy extends StatelessWidget {
} }
class _StatCellNum extends StatelessWidget { class _StatCellNum extends StatelessWidget {
const _StatCellNum({ const _StatCellNum(
super.key, {super.key,
required this.playerStat, required this.playerStat,
required this.playerStatLabel, required this.playerStatLabel,
}); this.snackBar});
final num playerStat; final num playerStat;
final String playerStatLabel; final String playerStatLabel;
final String? snackBar;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
Text( Text(
playerStat.toStringAsFixed(0), playerStat.floor().toString(),
style: const TextStyle( style: const TextStyle(
fontFamily: "Eurostile Round Extended", fontFamily: "Eurostile Round Extended",
color: Colors.white, color: Colors.white,
fontSize: 32, fontSize: 32,
), ),
), ),
Text( snackBar == null
playerStatLabel, ? Text(
textAlign: TextAlign.center, playerStatLabel,
style: const TextStyle( textAlign: TextAlign.center,
fontFamily: "Eurostile Round", style: const TextStyle(
color: Colors.white, fontFamily: "Eurostile Round",
fontSize: 16, color: Colors.white,
), fontSize: 16,
), ),
], )
); : TextButton(
} onPressed: () {
} ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(snackBar!)));
class _StatCellDuration extends StatelessWidget { },
const _StatCellDuration({ child: Text(
super.key, playerStatLabel,
required this.playerStat, textAlign: TextAlign.center,
required this.playerStatLabel, style: const TextStyle(
}); fontFamily: "Eurostile Round",
color: Colors.white,
final Duration playerStat; fontSize: 16,
final String playerStatLabel; ),
)),
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(
playerStat.toString().toString().split('.').first.padLeft(8, "0"),
style: const TextStyle(
fontFamily: "Eurostile Round Extended",
color: Colors.white,
fontSize: 32,
),
),
Text(
playerStatLabel,
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: "Eurostile Round",
color: Colors.white,
fontSize: 16,
),
),
], ],
); );
} }