Yeah I'm definitely getting somewhere,

but i need to think about that tab controller
This commit is contained in:
dan63047 2023-06-02 00:30:38 +03:00
parent d0a7315955
commit 73b648aaa2
80 changed files with 454 additions and 97 deletions

View File

@ -44,6 +44,8 @@ class TetrioPlayer {
required this.username,
required this.role,
required this.state,
this.avatarRevision,
this.bannerRevision,
this.registrationTime,
required this.badges,
this.bio,
@ -55,11 +57,14 @@ class TetrioPlayer {
required this.xp,
required this.supporterTier,
required this.verified,
this.badstanding,
this.bot,
required this.connections,
required this.tlSeason1,
required this.sprint,
required this.blitz,
this.zen,
this.distinguishment,
});
double get level =>
@ -94,6 +99,7 @@ class TetrioPlayer {
? Distinguishment.fromJson(json['distinguishment'])
: null;
friendCount = json['friend_count'] != null ? json['friend_count'] : 0;
badstanding = json['badstanding'] != null ? json['badstanding'] : null;
}
Future<void> getRecords() async {
@ -139,6 +145,8 @@ class TetrioPlayer {
data['bio'] = bio;
data['connections'] = connections.toJson();
data['friend_count'] = friendCount;
data['badstanding'] = badstanding;
data['bot'] = bot;
return data;
}
@ -563,6 +571,8 @@ class TetraLeagueAlpha {
this.vs,
this.records});
double get winrate => gamesWon / gamesPlayed;
TetraLeagueAlpha.fromJson(Map<String, dynamic> json) {
gamesPlayed = json['gamesplayed'];
gamesWon = json['gameswon'];
@ -586,6 +596,9 @@ class TetraLeagueAlpha {
}
double? get app => apm! / (pps! * 60);
double? get vsapm => vs! / apm!;
double? get dss => (vs! / 100) - (apm! / 60);
double? get dsp => ((vs! / 100) - (apm! / 60)) / pps!;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};

View File

@ -7,6 +7,9 @@ void main() {
databaseFactory = databaseFactoryFfi;
runApp(MaterialApp(
home: MainView(),
theme: ThemeData(fontFamily: 'Eurostile Round'),
theme: ThemeData(
fontFamily: 'Eurostile Round',
colorScheme: ColorScheme.dark(),
scaffoldBackgroundColor: Colors.black),
));
}

View File

@ -32,7 +32,7 @@ class MainView extends StatefulWidget {
}
Future<TetrioPlayer> fetchTetrioPlayer(String user) async {
var url = Uri.https('ch.tetr.io', 'api/users/$user');
var url = Uri.https('ch.tetr.io', 'api/users/${user.toLowerCase()}');
final response = await http.get(url);
// final response = await http.get(Uri.parse('https://ch.tetr.io/'));
@ -63,11 +63,7 @@ class _MainViewState extends State<MainView> {
Widget _searchTextField() {
return TextField(
decoration: const InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white))),
style: const TextStyle(
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(0.0, 0.0),
@ -92,7 +88,6 @@ class _MainViewState extends State<MainView> {
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
backgroundColor: Colors.black,
appBar: AppBar(
title: !_searchBoolean
? Text(
@ -163,18 +158,20 @@ class _MainViewState extends State<MainView> {
padding: const EdgeInsets.all(8),
children: [
_UserThingy(player: snapshot.data!),
_PlayerTabSection(context, snapshot.data!)
],
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}',
style: const TextStyle(
fontFamily: "Eurostile Round Extended",
color: Colors.white,
fontSize: 42));
return Center(
child: Text('${snapshot.error}',
style: const TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: 42)));
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
return const Center(
child: CircularProgressIndicator(
color: Colors.white,
));
},
),
),
@ -282,6 +279,9 @@ class _UserThingy extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
bool bigScreen = constraints.maxWidth > 768;
double bannerHeight = bigScreen ? 240 : 120;
double pfpHeight = bigScreen ? 64 : 32;
return Column(
children: [
Flex(
@ -296,24 +296,35 @@ class _UserThingy extends StatelessWidget {
Image.network(
"https://tetr.io/user-content/banners/${player.userId}.jpg?rv=${player.bannerRevision}",
fit: BoxFit.cover,
height: 240,
height: bannerHeight,
),
Container(
padding: EdgeInsets.fromLTRB(
0, player.bannerRevision != null ? 170 : 64, 0, 0),
0,
player.bannerRevision != null
? bannerHeight / 1.4
: pfpHeight,
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,
),
),
child: player.role == "banned"
? Image.asset(
"res/avatars/tetrio_banned.png",
fit: BoxFit.fitHeight,
height: 128,
)
: Image.network(
"https://tetr.io/user-content/avatars/${player.userId}.jpg?rv=${player.avatarRevision}",
fit: BoxFit.fitHeight,
height: 128,
errorBuilder: (context, error, stackTrace) =>
Image.asset(
"res/avatars/tetrio_anon.png",
fit: BoxFit.fitHeight,
height: 128,
),
),
),
),
],
@ -322,15 +333,13 @@ class _UserThingy extends StatelessWidget {
child: Column(
children: [
Text(player.username,
style: const TextStyle(
style: TextStyle(
fontFamily: "Eurostile Round Extended",
color: Colors.white,
fontSize: 42)),
fontSize: bigScreen ? 42 : 28)),
Text(
player.userId,
style: const TextStyle(
fontFamily: "Eurostile Round Condensed",
color: Colors.white,
fontSize: 14),
),
],
@ -348,7 +357,8 @@ class _UserThingy extends StatelessWidget {
children: [
_StatCellNum(
playerStat: player.level,
playerStatLabel: "Level",
playerStatLabel: "XP Level",
isScreenBig: bigScreen,
snackBar:
"${player.xp.floor().toString()} XP, ${((player.level - player.level.floor()) * 100).toStringAsFixed(2)} % until next level",
),
@ -356,32 +366,85 @@ class _UserThingy extends StatelessWidget {
_StatCellNum(
playerStat: (player.gameTime.inSeconds / 3600),
playerStatLabel: "Hours\nPlayed",
isScreenBig: bigScreen,
snackBar: player.gameTime.toString(),
),
if (player.gamesPlayed >= 0)
_StatCellNum(
playerStat: player.gamesPlayed,
playerStatLabel: "Games\nPlayed"),
isScreenBig: bigScreen,
playerStatLabel: "Online\nGames"),
if (player.gamesWon >= 0)
_StatCellNum(
playerStat: player.gamesWon,
isScreenBig: bigScreen,
playerStatLabel: "Games\nWon"),
if (player.friendCount > 0)
_StatCellNum(
playerStat: player.friendCount,
isScreenBig: bigScreen,
playerStatLabel: "Friends"),
],
)
: Text(
"BANNED",
textAlign: TextAlign.center,
style: const TextStyle(
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontWeight: FontWeight.w900,
color: Colors.red,
fontSize: 60,
fontSize: bigScreen ? 60 : 45,
),
),
if (player.badstanding != null)
player.badstanding!
? Text(
"BAD STANDING",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontWeight: FontWeight.w900,
color: Colors.red,
fontSize: bigScreen ? 60 : 45,
),
)
: const Text(
"Was in bad standing long time ago",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.red,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (player.country != null)
Text("${player.country?.toUpperCase()}",
style: const TextStyle(
fontFamily: "Eurostile Round",
fontSize: 16,
)),
Text(
"${player.role.capitalize()} account ${player.registrationTime == null ? "that was from very beginning" : 'created ${player.registrationTime}'}",
style: const TextStyle(
fontFamily: "Eurostile Round",
fontSize: 16,
)),
const Text("",
style: TextStyle(
fontFamily: "Eurostile Round",
fontSize: 16,
)),
Text(
player.supporterTier == 0
? "Not a supporter"
: "Supporter tier ${player.supporterTier}",
style: const TextStyle(
fontFamily: "Eurostile Round",
fontSize: 16,
)),
],
),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
@ -389,13 +452,55 @@ class _UserThingy extends StatelessWidget {
crossAxisAlignment: WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge,
children: [
Text(
"${player.role.capitalize()} account ${player.registrationTime == null ? "that was from very beginning" : 'created ${player.registrationTime}'}",
style: const TextStyle(
fontFamily: "Eurostile Round",
color: Colors.white,
fontSize: 16,
))
for (var badge in player.badges)
IconButton(
onPressed: () => showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(
badge.label,
style: const TextStyle(
fontFamily: "Eurostile Round Extended"),
),
content: SingleChildScrollView(
child: ListBody(
children: [
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
crossAxisAlignment:
WrapCrossAlignment.center,
spacing: 25,
children: [
Image.asset(
"res/tetrio_badges/${badge.badgeId}.png"),
Text(badge.ts != null
? "Obtained ${badge.ts}"
: "That badge was assigned manualy by TETR.IO admins"),
],
)
],
),
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
),
tooltip: badge.label,
icon: Image.asset(
"res/tetrio_badges/${badge.badgeId}.png",
height: 64,
width: 64,
))
],
),
],
@ -406,25 +511,29 @@ class _UserThingy extends StatelessWidget {
class _StatCellNum extends StatelessWidget {
const _StatCellNum(
{super.key,
required this.playerStat,
{required this.playerStat,
required this.playerStatLabel,
this.snackBar});
required this.isScreenBig,
this.snackBar,
this.fractionDigits});
final num playerStat;
final String playerStatLabel;
final bool isScreenBig;
final String? snackBar;
final int? fractionDigits;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(
playerStat.floor().toString(),
style: const TextStyle(
fractionDigits != null
? playerStat.toStringAsFixed(fractionDigits!)
: playerStat.floor().toString(),
style: TextStyle(
fontFamily: "Eurostile Round Extended",
color: Colors.white,
fontSize: 32,
fontSize: isScreenBig ? 32 : 24,
),
),
snackBar == null
@ -433,7 +542,6 @@ class _StatCellNum extends StatelessWidget {
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: "Eurostile Round",
color: Colors.white,
fontSize: 16,
),
)
@ -447,7 +555,6 @@ class _StatCellNum extends StatelessWidget {
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: "Eurostile Round",
color: Colors.white,
fontSize: 16,
),
)),
@ -455,3 +562,204 @@ class _StatCellNum extends StatelessWidget {
);
}
}
Widget _PlayerTabSection(BuildContext context, TetrioPlayer player) {
bool bigScreen = MediaQuery.of(context).size.width > 768;
return DefaultTabController(
length: 4,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
child: TabBar(tabs: [
Tab(text: "Tetra League"),
Tab(text: "40 Lines"),
Tab(text: "Blitz"),
Tab(text: "Other"),
]),
),
Container(
//Add this to give height
height: MediaQuery.of(context).size.height,
child: TabBarView(children: [
Container(
child: Column(
children: (player.tlSeason1.gamesPlayed > 0)
? [
Text("Tetra League",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
if (player.tlSeason1.gamesPlayed >= 10)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"res/tetrio_tl_alpha_ranks/${player.tlSeason1.rank}.png",
height: bigScreen ? 128 : 64,
),
Column(
children: [
Text(
"${player.tlSeason1.rating.toStringAsFixed(2)} TR",
style: TextStyle(
fontFamily:
"Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
Text(
"Top ${(player.tlSeason1.percentile * 100).toStringAsFixed(2)}% • Top Rank: ${player.tlSeason1.bestRank.toUpperCase()} • Glicko: ${player.tlSeason1.glicko?.toStringAsFixed(2)}±${player.tlSeason1.rd?.toStringAsFixed(2)}${player.tlSeason1.decaying ? ' • Decaying' : ''}")
],
)
],
)
else
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Text(
"${10 - player.tlSeason1.gamesPlayed} games until being ranked",
softWrap: true,
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28,
overflow: TextOverflow.visible,
)),
//Text("Top ${(player.tlSeason1.percentile * 100).toStringAsFixed(2)}% • Glicko: ${player.tlSeason1.glicko?.toStringAsFixed(2)}±${player.tlSeason1.rd?.toStringAsFixed(2)}${player.tlSeason1.decaying ? ' • Decaying' : ''}")
],
)
],
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 16, 0, 48),
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
spacing: 25,
crossAxisAlignment: WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge,
children: [
if (player.tlSeason1.apm != null)
_StatCellNum(
playerStat: player.tlSeason1.apm!,
isScreenBig: bigScreen,
fractionDigits: 2,
playerStatLabel: "Attack\nPer Minute"),
if (player.tlSeason1.pps != null)
_StatCellNum(
playerStat: player.tlSeason1.pps!,
isScreenBig: bigScreen,
fractionDigits: 2,
playerStatLabel: "Pieces\nPer Second"),
if (player.tlSeason1.apm != null)
_StatCellNum(
playerStat: player.tlSeason1.vs!,
isScreenBig: bigScreen,
fractionDigits: 2,
playerStatLabel: "Versus\nScore"),
if (player.tlSeason1.standing > 0)
_StatCellNum(
playerStat: player.tlSeason1.standing,
isScreenBig: bigScreen,
playerStatLabel: "Leaderboard\nplacement"),
if (player.tlSeason1.standingLocal > 0)
_StatCellNum(
playerStat: player.tlSeason1.standingLocal,
isScreenBig: bigScreen,
playerStatLabel: "Country LB\nplacement"),
_StatCellNum(
playerStat: player.tlSeason1.gamesPlayed,
isScreenBig: bigScreen,
playerStatLabel: "Games\nplayed"),
_StatCellNum(
playerStat: player.tlSeason1.gamesWon,
isScreenBig: bigScreen,
playerStatLabel: "Games\nwon"),
_StatCellNum(
playerStat: player.tlSeason1.winrate * 100,
isScreenBig: bigScreen,
fractionDigits: 2,
playerStatLabel: "Winrate\nprecentage"),
],
),
),
if (player.tlSeason1.apm != null &&
player.tlSeason1.pps != null &&
player.tlSeason1.apm != null)
Column(
children: [
Text("Nerd Stats",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
Padding(
padding:
const EdgeInsets.fromLTRB(0, 16, 0, 48),
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
spacing: 25,
crossAxisAlignment:
WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge,
children: [
_StatCellNum(
playerStat: player.tlSeason1.app!,
isScreenBig: bigScreen,
fractionDigits: 3,
playerStatLabel: "Attack\nPer Piece"),
_StatCellNum(
playerStat: player.tlSeason1.vsapm!,
isScreenBig: bigScreen,
fractionDigits: 3,
playerStatLabel: "VS/APM"),
_StatCellNum(
playerStat: player.tlSeason1.dss!,
isScreenBig: bigScreen,
fractionDigits: 3,
playerStatLabel:
"Downstack\nPer Second"),
_StatCellNum(
playerStat: player.tlSeason1.dsp!,
isScreenBig: bigScreen,
fractionDigits: 3,
playerStatLabel:
"Downstack\nPer Piece"),
]),
)
],
)
]
: [
Text("That user never played Tetra League",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
],
),
),
Container(
child: Text("40 Lines",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
),
Container(
child: Text("Blitz",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
),
Container(
child: Text("Other info",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
),
]),
),
],
),
);
}

View File

@ -1,8 +1,6 @@
name: tetra_stats
description: Track your and other player stats in TETR.IO
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
publish_to: 'none'
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
@ -31,10 +29,6 @@ dependencies:
http:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
sqflite: ^2.2.8+2
sqflite_common_ffi: any
@ -44,55 +38,94 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
assets:
- res/avatars/tetrio_anon.png
- res/avatars/tetrio_banned.png
- res/tetrio_tl_alpha_ranks/x.png
- res/tetrio_tl_alpha_ranks/u.png
- res/tetrio_tl_alpha_ranks/ss.png
- res/tetrio_tl_alpha_ranks/s+.png
- res/tetrio_tl_alpha_ranks/s.png
- res/tetrio_tl_alpha_ranks/s-.png
- res/tetrio_tl_alpha_ranks/a+.png
- res/tetrio_tl_alpha_ranks/a.png
- res/tetrio_tl_alpha_ranks/a-.png
- res/tetrio_tl_alpha_ranks/b+.png
- res/tetrio_tl_alpha_ranks/b.png
- res/tetrio_tl_alpha_ranks/b-.png
- res/tetrio_tl_alpha_ranks/c+.png
- res/tetrio_tl_alpha_ranks/c.png
- res/tetrio_tl_alpha_ranks/c-.png
- res/tetrio_tl_alpha_ranks/d+.png
- res/tetrio_tl_alpha_ranks/d.png
- res/tetrio_tl_alpha_ranks/z.png
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
- res/tetrio_badges/5mblast_1.png
- res/tetrio_badges/5mblast_10.png
- res/tetrio_badges/5mblast_100.png
- res/tetrio_badges/5mblast_1000.png
- res/tetrio_badges/20tsd.png
- res/tetrio_badges/100player.png
- res/tetrio_badges/allclear.png
- res/tetrio_badges/bugbounty.png
- res/tetrio_badges/cometopen_1.png
- res/tetrio_badges/cometopen_2.png
- res/tetrio_badges/cometopen_3.png
- res/tetrio_badges/early-supporter.png
- res/tetrio_badges/founder.png
- res/tetrio_badges/galactic2x2_1.png
- res/tetrio_badges/ggc_2.png
- res/tetrio_badges/heart.png
- res/tetrio_badges/hnprism_1.png
- res/tetrio_badges/hnprism_2.png
- res/tetrio_badges/ift_1.png
- res/tetrio_badges/ift_2.png
- res/tetrio_badges/ift_3.png
- res/tetrio_badges/infdev.png
- res/tetrio_badges/kod_by_founder.png
- res/tetrio_badges/kod_founder.png
- res/tetrio_badges/leaderboard1.png
- res/tetrio_badges/mmc_tabi_1.png
- res/tetrio_badges/mmc_tabi_2.png
- res/tetrio_badges/mmc_tabi_3.png
- res/tetrio_badges/mmc_tabi_superlobby.png
- res/tetrio_badges/mmc_tabi_superlobby2.png
- res/tetrio_badges/mmc_tabi_superlobby3.png
- res/tetrio_badges/redgevo_2.png
- res/tetrio_badges/redgevo_3.png
- res/tetrio_badges/rengervl_1.png
- res/tetrio_badges/rengervl_2.png
- res/tetrio_badges/rengervl_3.png
- res/tetrio_badges/sakurablend_1.png
- res/tetrio_badges/scuncapped_1.png
- res/tetrio_badges/scuncapped_2.png
- res/tetrio_badges/secretgrade.png
- res/tetrio_badges/sfu_raccoon_1.png
- res/tetrio_badges/superlobby.png
- res/tetrio_badges/superlobby2.png
- res/tetrio_badges/tawshdsl_uncapped.png
- res/tetrio_badges/tawsignite_expert.png
- res/tetrio_badges/tawslg.png
- res/tetrio_badges/tetralympic_masters.png
- res/tetrio_badges/ttsdtc_1.png
- res/tetrio_badges/ttsdtc_2.png
- res/tetrio_badges/ttsdtc_3.png
- res/tetrio_badges/underdog_predict.png
- res/tetrio_badges/wpl_1.png
- res/tetrio_badges/wplc_1.png
- res/tetrio_badges/wplc_2.png
- res/tetrio_badges/wplc_3.png
- res/tetrio_badges/wplc_participation.png
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
fonts:
- family: Eurostile Round
fonts:

BIN
res/avatars/tetrio_anon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
res/tetrio_badges/20tsd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
res/tetrio_badges/ggc_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
res/tetrio_badges/heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
res/tetrio_badges/ift_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
res/tetrio_badges/ift_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
res/tetrio_badges/ift_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
res/tetrio_badges/wpl_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB