1.5.0
|
@ -16,6 +16,7 @@ You can [download an app](https://github.com/dan63047/TetraStats/releases), or [
|
|||
- Stats Calculator
|
||||
- Player history in charts
|
||||
- Tetra League matches history
|
||||
- Time-weighted stats in Tetra League matches
|
||||
|
||||
# Special thanks
|
||||
- **kerrmunism** — formulas
|
||||
|
|
|
@ -25,6 +25,12 @@ apply plugin: 'com.android.application'
|
|||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion flutter.compileSdkVersion
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
@ -53,11 +59,17 @@ android {
|
|||
versionName flutterVersionName
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
//import 'dart:convert';
|
||||
import 'dart:io';
|
||||
//import 'dart:io';
|
||||
|
||||
//import 'package:path_provider/path_provider.dart';
|
||||
|
||||
//import 'tetrio_multiplayer_replay.dart';
|
||||
|
||||
/// That thing allows me to test my new staff i'm trying to implement
|
||||
void main() async {
|
||||
//void main() async {
|
||||
// List<Tetromino> queue = List.from(tetrominoes);
|
||||
// TetrioRNG rng = TetrioRNG(0);
|
||||
// queue = rng.shuffleList(queue);
|
||||
|
@ -21,5 +21,5 @@ void main() async {
|
|||
// print(replay.rawJson);
|
||||
|
||||
//print("");
|
||||
exit(0);
|
||||
}
|
||||
// exit(0);
|
||||
//}
|
|
@ -261,399 +261,399 @@ class ReplayData{
|
|||
|
||||
// can't belive i have to implement that difficult shit
|
||||
|
||||
List<Event> readEventList(Map<dynamic, dynamic> json){
|
||||
List<Event> events = [];
|
||||
int id = 0;
|
||||
for (var event in json['data'][0]['replays'][0]['events']){
|
||||
int frame = event["frame"];
|
||||
EventType type = EventType.values.byName(event['type']);
|
||||
switch (type) {
|
||||
case EventType.start:
|
||||
events.add(Event(id, frame, type));
|
||||
break;
|
||||
case EventType.full:
|
||||
events.add(EventFull(id, frame, type, DataFull.fromJson(event["data"])));
|
||||
break;
|
||||
case EventType.targets:
|
||||
// TODO
|
||||
break;
|
||||
case EventType.keydown:
|
||||
events.add(EventKeyPress(id, frame, type,
|
||||
Keypress(
|
||||
KeyType.values.byName(event['data']['key']),
|
||||
event['data']['subframe'],
|
||||
false)
|
||||
));
|
||||
break;
|
||||
case EventType.keyup:
|
||||
events.add(EventKeyPress(id, frame, type,
|
||||
Keypress(
|
||||
KeyType.values.byName(event['data']['key']),
|
||||
event['data']['subframe'],
|
||||
true)
|
||||
));
|
||||
break;
|
||||
case EventType.end:
|
||||
// TODO: Handle this case.
|
||||
case EventType.ige:
|
||||
// TODO: Handle this case.
|
||||
case EventType.exit:
|
||||
// TODO: Handle this case.
|
||||
}
|
||||
id++;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
// List<Event> readEventList(Map<dynamic, dynamic> json){
|
||||
// List<Event> events = [];
|
||||
// int id = 0;
|
||||
// for (var event in json['data'][0]['replays'][0]['events']){
|
||||
// int frame = event["frame"];
|
||||
// EventType type = EventType.values.byName(event['type']);
|
||||
// switch (type) {
|
||||
// case EventType.start:
|
||||
// events.add(Event(id, frame, type));
|
||||
// break;
|
||||
// case EventType.full:
|
||||
// events.add(EventFull(id, frame, type, DataFull.fromJson(event["data"])));
|
||||
// break;
|
||||
// case EventType.targets:
|
||||
// // TODO
|
||||
// break;
|
||||
// case EventType.keydown:
|
||||
// events.add(EventKeyPress(id, frame, type,
|
||||
// Keypress(
|
||||
// KeyType.values.byName(event['data']['key']),
|
||||
// event['data']['subframe'],
|
||||
// false)
|
||||
// ));
|
||||
// break;
|
||||
// case EventType.keyup:
|
||||
// events.add(EventKeyPress(id, frame, type,
|
||||
// Keypress(
|
||||
// KeyType.values.byName(event['data']['key']),
|
||||
// event['data']['subframe'],
|
||||
// true)
|
||||
// ));
|
||||
// break;
|
||||
// case EventType.end:
|
||||
// // TODO: Handle this case.
|
||||
// case EventType.ige:
|
||||
// // TODO: Handle this case.
|
||||
// case EventType.exit:
|
||||
// // TODO: Handle this case.
|
||||
// }
|
||||
// id++;
|
||||
// }
|
||||
// return [];
|
||||
// }
|
||||
|
||||
enum EventType
|
||||
{
|
||||
start,
|
||||
end,
|
||||
full,
|
||||
keydown,
|
||||
keyup,
|
||||
targets,
|
||||
ige,
|
||||
exit
|
||||
}
|
||||
// enum EventType
|
||||
// {
|
||||
// start,
|
||||
// end,
|
||||
// full,
|
||||
// keydown,
|
||||
// keyup,
|
||||
// targets,
|
||||
// ige,
|
||||
// exit
|
||||
// }
|
||||
|
||||
enum KeyType
|
||||
{
|
||||
moveLeft,
|
||||
moveRight,
|
||||
softDrop,
|
||||
rotateCCW,
|
||||
rotateCW,
|
||||
rotate180,
|
||||
hardDrop,
|
||||
hold,
|
||||
chat,
|
||||
exit,
|
||||
retry
|
||||
}
|
||||
// enum KeyType
|
||||
// {
|
||||
// moveLeft,
|
||||
// moveRight,
|
||||
// softDrop,
|
||||
// rotateCCW,
|
||||
// rotateCW,
|
||||
// rotate180,
|
||||
// hardDrop,
|
||||
// hold,
|
||||
// chat,
|
||||
// exit,
|
||||
// retry
|
||||
// }
|
||||
|
||||
class Event{
|
||||
int id;
|
||||
int frame;
|
||||
EventType type;
|
||||
//dynamic data;
|
||||
// class Event{
|
||||
// int id;
|
||||
// int frame;
|
||||
// EventType type;
|
||||
// //dynamic data;
|
||||
|
||||
Event(this.id, this.frame, this.type);
|
||||
// Event(this.id, this.frame, this.type);
|
||||
|
||||
@override
|
||||
String toString(){
|
||||
return "E#$id f#$frame: $type";
|
||||
}
|
||||
}
|
||||
// @override
|
||||
// String toString(){
|
||||
// return "E#$id f#$frame: $type";
|
||||
// }
|
||||
// }
|
||||
|
||||
class Keypress{
|
||||
KeyType key;
|
||||
double subframe;
|
||||
bool released;
|
||||
// class Keypress{
|
||||
// KeyType key;
|
||||
// double subframe;
|
||||
// bool released;
|
||||
|
||||
Keypress(this.key, this.subframe, this.released);
|
||||
}
|
||||
// Keypress(this.key, this.subframe, this.released);
|
||||
// }
|
||||
|
||||
class EventKeyPress extends Event{
|
||||
Keypress data;
|
||||
// class EventKeyPress extends Event{
|
||||
// Keypress data;
|
||||
|
||||
EventKeyPress(super.id, super.frame, super.type, this.data);
|
||||
}
|
||||
// EventKeyPress(super.id, super.frame, super.type, this.data);
|
||||
// }
|
||||
|
||||
class IGE{
|
||||
int id;
|
||||
int frame;
|
||||
String type;
|
||||
int amount;
|
||||
// class IGE{
|
||||
// int id;
|
||||
// int frame;
|
||||
// String type;
|
||||
// int amount;
|
||||
|
||||
IGE(this.id, this.frame, this.type, this.amount);
|
||||
}
|
||||
// IGE(this.id, this.frame, this.type, this.amount);
|
||||
// }
|
||||
|
||||
class EventIGE extends Event{
|
||||
IGE data;
|
||||
// class EventIGE extends Event{
|
||||
// IGE data;
|
||||
|
||||
EventIGE(super.id, super.frame, super.type, this.data);
|
||||
}
|
||||
// EventIGE(super.id, super.frame, super.type, this.data);
|
||||
// }
|
||||
|
||||
class Hold
|
||||
{
|
||||
String? piece;
|
||||
bool locked;
|
||||
// class Hold
|
||||
// {
|
||||
// String? piece;
|
||||
// bool locked;
|
||||
|
||||
Hold(this.piece, this.locked);
|
||||
}
|
||||
// Hold(this.piece, this.locked);
|
||||
// }
|
||||
|
||||
class DataFullOptions{
|
||||
int? version;
|
||||
bool? seedRandom;
|
||||
int? seed;
|
||||
double? g;
|
||||
int? stock;
|
||||
int? gMargin;
|
||||
double? gIncrease;
|
||||
double? garbageMultiplier;
|
||||
int? garbageMargin;
|
||||
double? garbageIncrease;
|
||||
int? garbageCap;
|
||||
double? garbageCapIncrease;
|
||||
int? garbageCapMax;
|
||||
int? garbageHoleSize;
|
||||
String? garbageBlocking; // TODO: enum
|
||||
bool? hasGarbage;
|
||||
int? locktime;
|
||||
int? garbageSpeed;
|
||||
int? forfeitTime;
|
||||
int? are;
|
||||
int? areLineclear;
|
||||
bool? infiniteMovement;
|
||||
int? lockresets;
|
||||
bool? allow180;
|
||||
bool? btbChaining;
|
||||
bool? allclears;
|
||||
bool? clutch;
|
||||
bool? noLockout;
|
||||
String? passthrough;
|
||||
int? boardwidth;
|
||||
int? boardheight;
|
||||
Handling? handling;
|
||||
int? boardbuffer;
|
||||
// class DataFullOptions{
|
||||
// int? version;
|
||||
// bool? seedRandom;
|
||||
// int? seed;
|
||||
// double? g;
|
||||
// int? stock;
|
||||
// int? gMargin;
|
||||
// double? gIncrease;
|
||||
// double? garbageMultiplier;
|
||||
// int? garbageMargin;
|
||||
// double? garbageIncrease;
|
||||
// int? garbageCap;
|
||||
// double? garbageCapIncrease;
|
||||
// int? garbageCapMax;
|
||||
// int? garbageHoleSize;
|
||||
// String? garbageBlocking; // TODO: enum
|
||||
// bool? hasGarbage;
|
||||
// int? locktime;
|
||||
// int? garbageSpeed;
|
||||
// int? forfeitTime;
|
||||
// int? are;
|
||||
// int? areLineclear;
|
||||
// bool? infiniteMovement;
|
||||
// int? lockresets;
|
||||
// bool? allow180;
|
||||
// bool? btbChaining;
|
||||
// bool? allclears;
|
||||
// bool? clutch;
|
||||
// bool? noLockout;
|
||||
// String? passthrough;
|
||||
// int? boardwidth;
|
||||
// int? boardheight;
|
||||
// Handling? handling;
|
||||
// int? boardbuffer;
|
||||
|
||||
DataFullOptions.fromJson(Map<String, dynamic> json){
|
||||
version = json["version"];
|
||||
seedRandom = json["seed_random"];
|
||||
seed = json["seed"];
|
||||
g = json["g"];
|
||||
stock = json["stock"];
|
||||
gMargin = json["gmargin"];
|
||||
gIncrease = json["gincrease"];
|
||||
garbageMultiplier = json["garbagemultiplier"];
|
||||
garbageCapIncrease = json["garbagecapincrease"];
|
||||
garbageCapMax = json["garbagecapmax"];
|
||||
garbageHoleSize = json["garbageholesize"];
|
||||
garbageBlocking = json["garbageblocking"];
|
||||
hasGarbage = json["hasgarbage"];
|
||||
locktime = json["locktime"];
|
||||
garbageSpeed = json["garbagespeed"];
|
||||
forfeitTime = json["forfeit_time"];
|
||||
are = json["are"];
|
||||
areLineclear = json["lineclear_are"];
|
||||
infiniteMovement = json["infinitemovement"];
|
||||
lockresets = json["lockresets"];
|
||||
allow180 = json["allow180"];
|
||||
btbChaining = json["b2bchaining"];
|
||||
allclears = json["allclears"];
|
||||
clutch = json["clutch"];
|
||||
noLockout = json["nolockout"];
|
||||
passthrough = json["passthrough"];
|
||||
boardwidth = json["boardwidth"];
|
||||
boardheight = json["boardheight"];
|
||||
handling = Handling.fromJson(json["handling"]);
|
||||
boardbuffer = json["boardbuffer"];
|
||||
}
|
||||
}
|
||||
// DataFullOptions.fromJson(Map<String, dynamic> json){
|
||||
// version = json["version"];
|
||||
// seedRandom = json["seed_random"];
|
||||
// seed = json["seed"];
|
||||
// g = json["g"];
|
||||
// stock = json["stock"];
|
||||
// gMargin = json["gmargin"];
|
||||
// gIncrease = json["gincrease"];
|
||||
// garbageMultiplier = json["garbagemultiplier"];
|
||||
// garbageCapIncrease = json["garbagecapincrease"];
|
||||
// garbageCapMax = json["garbagecapmax"];
|
||||
// garbageHoleSize = json["garbageholesize"];
|
||||
// garbageBlocking = json["garbageblocking"];
|
||||
// hasGarbage = json["hasgarbage"];
|
||||
// locktime = json["locktime"];
|
||||
// garbageSpeed = json["garbagespeed"];
|
||||
// forfeitTime = json["forfeit_time"];
|
||||
// are = json["are"];
|
||||
// areLineclear = json["lineclear_are"];
|
||||
// infiniteMovement = json["infinitemovement"];
|
||||
// lockresets = json["lockresets"];
|
||||
// allow180 = json["allow180"];
|
||||
// btbChaining = json["b2bchaining"];
|
||||
// allclears = json["allclears"];
|
||||
// clutch = json["clutch"];
|
||||
// noLockout = json["nolockout"];
|
||||
// passthrough = json["passthrough"];
|
||||
// boardwidth = json["boardwidth"];
|
||||
// boardheight = json["boardheight"];
|
||||
// handling = Handling.fromJson(json["handling"]);
|
||||
// boardbuffer = json["boardbuffer"];
|
||||
// }
|
||||
// }
|
||||
|
||||
class DataFullStats
|
||||
{
|
||||
double? seed;
|
||||
int? lines;
|
||||
int? levelLines;
|
||||
int? levelLinesNeeded;
|
||||
int? inputs;
|
||||
int? holds;
|
||||
int? score;
|
||||
int? zenLevel;
|
||||
int? zenProgress;
|
||||
int? level;
|
||||
int? combo;
|
||||
int? currentComboPower;
|
||||
int? topCombo;
|
||||
int? btb;
|
||||
int? topbtb;
|
||||
int? tspins;
|
||||
int? piecesPlaced;
|
||||
Clears? clears;
|
||||
Garbage? garbage;
|
||||
int? kills;
|
||||
Finesse? finesse;
|
||||
// class DataFullStats
|
||||
// {
|
||||
// double? seed;
|
||||
// int? lines;
|
||||
// int? levelLines;
|
||||
// int? levelLinesNeeded;
|
||||
// int? inputs;
|
||||
// int? holds;
|
||||
// int? score;
|
||||
// int? zenLevel;
|
||||
// int? zenProgress;
|
||||
// int? level;
|
||||
// int? combo;
|
||||
// int? currentComboPower;
|
||||
// int? topCombo;
|
||||
// int? btb;
|
||||
// int? topbtb;
|
||||
// int? tspins;
|
||||
// int? piecesPlaced;
|
||||
// Clears? clears;
|
||||
// Garbage? garbage;
|
||||
// int? kills;
|
||||
// Finesse? finesse;
|
||||
|
||||
DataFullStats.fromJson(Map<String, dynamic> json){
|
||||
seed = json["seed"];
|
||||
lines = json["lines"];
|
||||
levelLines = json["level_lines"];
|
||||
levelLinesNeeded = json["level_lines_needed"];
|
||||
inputs = json["inputs"];
|
||||
holds = json["holds"];
|
||||
score = json["score"];
|
||||
zenLevel = json["zenlevel"];
|
||||
zenProgress = json["zenprogress"];
|
||||
level = json["level"];
|
||||
combo = json["combo"];
|
||||
currentComboPower = json["currentcombopower"];
|
||||
topCombo = json["topcombo"];
|
||||
btb = json["btb"];
|
||||
topbtb = json["topbtb"];
|
||||
tspins = json["tspins"];
|
||||
piecesPlaced = json["piecesplaced"];
|
||||
clears = Clears.fromJson(json["clears"]);
|
||||
garbage = Garbage.fromJson(json["garbage"]);
|
||||
kills = json["kills"];
|
||||
finesse = Finesse.fromJson(json["finesse"]);
|
||||
}
|
||||
}
|
||||
// DataFullStats.fromJson(Map<String, dynamic> json){
|
||||
// seed = json["seed"];
|
||||
// lines = json["lines"];
|
||||
// levelLines = json["level_lines"];
|
||||
// levelLinesNeeded = json["level_lines_needed"];
|
||||
// inputs = json["inputs"];
|
||||
// holds = json["holds"];
|
||||
// score = json["score"];
|
||||
// zenLevel = json["zenlevel"];
|
||||
// zenProgress = json["zenprogress"];
|
||||
// level = json["level"];
|
||||
// combo = json["combo"];
|
||||
// currentComboPower = json["currentcombopower"];
|
||||
// topCombo = json["topcombo"];
|
||||
// btb = json["btb"];
|
||||
// topbtb = json["topbtb"];
|
||||
// tspins = json["tspins"];
|
||||
// piecesPlaced = json["piecesplaced"];
|
||||
// clears = Clears.fromJson(json["clears"]);
|
||||
// garbage = Garbage.fromJson(json["garbage"]);
|
||||
// kills = json["kills"];
|
||||
// finesse = Finesse.fromJson(json["finesse"]);
|
||||
// }
|
||||
// }
|
||||
|
||||
class DataFullGame
|
||||
{
|
||||
List<List<String?>>? board;
|
||||
List<String>? bag;
|
||||
double? g;
|
||||
bool? playing;
|
||||
Hold? hold;
|
||||
String? piece;
|
||||
Handling? handling;
|
||||
// class DataFullGame
|
||||
// {
|
||||
// List<List<String?>>? board;
|
||||
// List<String>? bag;
|
||||
// double? g;
|
||||
// bool? playing;
|
||||
// Hold? hold;
|
||||
// String? piece;
|
||||
// Handling? handling;
|
||||
|
||||
DataFullGame.fromJson(Map<String, dynamic> json){
|
||||
board = json["board"];
|
||||
bag = json["bag"];
|
||||
hold = Hold(json["hold"]["piece"], json["hold"]["locked"]);
|
||||
g = json["g"];
|
||||
handling = Handling.fromJson(json["handling"]);
|
||||
}
|
||||
}
|
||||
// DataFullGame.fromJson(Map<String, dynamic> json){
|
||||
// board = json["board"];
|
||||
// bag = json["bag"];
|
||||
// hold = Hold(json["hold"]["piece"], json["hold"]["locked"]);
|
||||
// g = json["g"];
|
||||
// handling = Handling.fromJson(json["handling"]);
|
||||
// }
|
||||
// }
|
||||
|
||||
class DataFull{
|
||||
bool? successful;
|
||||
String? gameOverReason;
|
||||
int? fire;
|
||||
DataFullOptions? options;
|
||||
DataFullStats? stats;
|
||||
DataFullGame? game;
|
||||
// class DataFull{
|
||||
// bool? successful;
|
||||
// String? gameOverReason;
|
||||
// int? fire;
|
||||
// DataFullOptions? options;
|
||||
// DataFullStats? stats;
|
||||
// DataFullGame? game;
|
||||
|
||||
DataFull.fromJson(Map<String, dynamic> json){
|
||||
successful = json["successful"];
|
||||
gameOverReason = json["gameoverreason"];
|
||||
fire = json["fire"];
|
||||
options = DataFullOptions.fromJson(json["options"]);
|
||||
stats = DataFullStats.fromJson(json["stats"]);
|
||||
game = DataFullGame.fromJson(json["game"]);
|
||||
}
|
||||
}
|
||||
// DataFull.fromJson(Map<String, dynamic> json){
|
||||
// successful = json["successful"];
|
||||
// gameOverReason = json["gameoverreason"];
|
||||
// fire = json["fire"];
|
||||
// options = DataFullOptions.fromJson(json["options"]);
|
||||
// stats = DataFullStats.fromJson(json["stats"]);
|
||||
// game = DataFullGame.fromJson(json["game"]);
|
||||
// }
|
||||
// }
|
||||
|
||||
class EventFull extends Event{
|
||||
DataFull data;
|
||||
// class EventFull extends Event{
|
||||
// DataFull data;
|
||||
|
||||
EventFull(super.id, super.frame, super.type, this.data);
|
||||
}
|
||||
// EventFull(super.id, super.frame, super.type, this.data);
|
||||
// }
|
||||
|
||||
class TetrioRNG{
|
||||
late double _t;
|
||||
// class TetrioRNG{
|
||||
// late double _t;
|
||||
|
||||
TetrioRNG(int seed){
|
||||
_t = seed % 2147483647;
|
||||
if (_t <= 0) _t += 2147483646;
|
||||
}
|
||||
// TetrioRNG(int seed){
|
||||
// _t = seed % 2147483647;
|
||||
// if (_t <= 0) _t += 2147483646;
|
||||
// }
|
||||
|
||||
int next(){
|
||||
_t = 16807 * _t % 2147483647;
|
||||
return _t.toInt();
|
||||
}
|
||||
// int next(){
|
||||
// _t = 16807 * _t % 2147483647;
|
||||
// return _t.toInt();
|
||||
// }
|
||||
|
||||
double nextFloat(){
|
||||
return (next() - 1) / 2147483646;
|
||||
}
|
||||
// double nextFloat(){
|
||||
// return (next() - 1) / 2147483646;
|
||||
// }
|
||||
|
||||
List<Tetromino> shuffleList(List<Tetromino> array){
|
||||
int length = array.length;
|
||||
if (length == 0) return [];
|
||||
// List<Tetromino> shuffleList(List<Tetromino> array){
|
||||
// int length = array.length;
|
||||
// if (length == 0) return [];
|
||||
|
||||
for (; --length > 0;){
|
||||
int swapIndex = ((nextFloat()) * (length + 1)).toInt();
|
||||
Tetromino tmp = array[length];
|
||||
array[length] = array[swapIndex];
|
||||
array[swapIndex] = tmp;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
// for (; --length > 0;){
|
||||
// int swapIndex = ((nextFloat()) * (length + 1)).toInt();
|
||||
// Tetromino tmp = array[length];
|
||||
// array[length] = array[swapIndex];
|
||||
// array[swapIndex] = tmp;
|
||||
// }
|
||||
// return array;
|
||||
// }
|
||||
// }
|
||||
|
||||
enum Tetromino{
|
||||
Z,
|
||||
L,
|
||||
O,
|
||||
S,
|
||||
I,
|
||||
J,
|
||||
T,
|
||||
garbage,
|
||||
empty
|
||||
}
|
||||
// enum Tetromino{
|
||||
// Z,
|
||||
// L,
|
||||
// O,
|
||||
// S,
|
||||
// I,
|
||||
// J,
|
||||
// T,
|
||||
// garbage,
|
||||
// empty
|
||||
// }
|
||||
|
||||
List<Tetromino> tetrominoes = [Tetromino.Z, Tetromino.L, Tetromino.O, Tetromino.S, Tetromino.I, Tetromino.J, Tetromino.T];
|
||||
List<List<List<Vector2>>> shapes = [
|
||||
[ // Z
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(2, 0), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(1, 2), Vector2(2, 2)],
|
||||
[Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(0, 2)]
|
||||
],
|
||||
[ // L
|
||||
[Vector2(2, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(1, 2), Vector2(2, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(0, 2)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(1, 2)]
|
||||
],
|
||||
[ // O
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)]
|
||||
],
|
||||
[ // S
|
||||
[Vector2(1, 0), Vector2(2, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(2, 1), Vector2(2, 2)],
|
||||
[Vector2(1, 1), Vector2(2, 1), Vector2(0, 2), Vector2(1, 2)],
|
||||
[Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 2)]
|
||||
],
|
||||
[ // I
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(3, 1)],
|
||||
[Vector2(2, 0), Vector2(2, 1), Vector2(2, 2), Vector2(2, 3)],
|
||||
[Vector2(0, 2), Vector2(1, 2), Vector2(2, 2), Vector2(3, 2)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(1, 2), Vector2(1, 3)]
|
||||
],
|
||||
[ // J
|
||||
[Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(1, 0), Vector2(2, 0), Vector2(1, 1), Vector2(1, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(2, 2)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(0, 2), Vector2(1, 2)]
|
||||
],
|
||||
[ // T
|
||||
[Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
[Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 2)]
|
||||
]
|
||||
];
|
||||
List<Vector2> spawnPositionFixes = [Vector2(1, 1), Vector2(1, 1), Vector2(0, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)];
|
||||
// List<Tetromino> tetrominoes = [Tetromino.Z, Tetromino.L, Tetromino.O, Tetromino.S, Tetromino.I, Tetromino.J, Tetromino.T];
|
||||
// List<List<List<Vector2>>> shapes = [
|
||||
// [ // Z
|
||||
// [Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(2, 1)],
|
||||
// [Vector2(2, 0), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
// [Vector2(0, 1), Vector2(1, 1), Vector2(1, 2), Vector2(2, 2)],
|
||||
// [Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(0, 2)]
|
||||
// ],
|
||||
// [ // L
|
||||
// [Vector2(2, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
// [Vector2(1, 0), Vector2(1, 1), Vector2(1, 2), Vector2(2, 2)],
|
||||
// [Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(0, 2)],
|
||||
// [Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(1, 2)]
|
||||
// ],
|
||||
// [ // O
|
||||
// [Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
// [Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
// [Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
// [Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)]
|
||||
// ],
|
||||
// [ // S
|
||||
// [Vector2(1, 0), Vector2(2, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
// [Vector2(1, 0), Vector2(1, 1), Vector2(2, 1), Vector2(2, 2)],
|
||||
// [Vector2(1, 1), Vector2(2, 1), Vector2(0, 2), Vector2(1, 2)],
|
||||
// [Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 2)]
|
||||
// ],
|
||||
// [ // I
|
||||
// [Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(3, 1)],
|
||||
// [Vector2(2, 0), Vector2(2, 1), Vector2(2, 2), Vector2(2, 3)],
|
||||
// [Vector2(0, 2), Vector2(1, 2), Vector2(2, 2), Vector2(3, 2)],
|
||||
// [Vector2(1, 0), Vector2(1, 1), Vector2(1, 2), Vector2(1, 3)]
|
||||
// ],
|
||||
// [ // J
|
||||
// [Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
// [Vector2(1, 0), Vector2(2, 0), Vector2(1, 1), Vector2(1, 2)],
|
||||
// [Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(2, 2)],
|
||||
// [Vector2(1, 0), Vector2(1, 1), Vector2(0, 2), Vector2(1, 2)]
|
||||
// ],
|
||||
// [ // T
|
||||
// [Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
// [Vector2(1, 0), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
// [Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
// [Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 2)]
|
||||
// ]
|
||||
// ];
|
||||
// List<Vector2> spawnPositionFixes = [Vector2(1, 1), Vector2(1, 1), Vector2(0, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)];
|
||||
|
||||
const Map<String, double> garbage = {
|
||||
"single": 0,
|
||||
"double": 1,
|
||||
"triple": 2,
|
||||
"quad": 4,
|
||||
"penta": 5,
|
||||
"t-spin": 0,
|
||||
"t-spin single": 2,
|
||||
"t-spin double": 4,
|
||||
"t-spin triple": 6,
|
||||
"t-spin quad": 10,
|
||||
"t-spin penta": 12,
|
||||
"t-spin mini": 0,
|
||||
"t-spin mini single": 0,
|
||||
"t-spin mini double": 1,
|
||||
"allclear": 10
|
||||
};
|
||||
int btbBonus = 1;
|
||||
double btbLog = 0.8;
|
||||
double comboBonus = 0.25;
|
||||
int comboMinifier = 1;
|
||||
double comboMinifierLog = 1.25;
|
||||
List<int> comboTable = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5];
|
||||
// const Map<String, double> garbage = {
|
||||
// "single": 0,
|
||||
// "double": 1,
|
||||
// "triple": 2,
|
||||
// "quad": 4,
|
||||
// "penta": 5,
|
||||
// "t-spin": 0,
|
||||
// "t-spin single": 2,
|
||||
// "t-spin double": 4,
|
||||
// "t-spin triple": 6,
|
||||
// "t-spin quad": 10,
|
||||
// "t-spin penta": 12,
|
||||
// "t-spin mini": 0,
|
||||
// "t-spin mini single": 0,
|
||||
// "t-spin mini double": 1,
|
||||
// "allclear": 10
|
||||
// };
|
||||
// int btbBonus = 1;
|
||||
// double btbLog = 0.8;
|
||||
// double comboBonus = 0.25;
|
||||
// int comboMinifier = 1;
|
||||
// double comboMinifierLog = 1.25;
|
||||
// List<int> comboTable = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5];
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 2
|
||||
/// Strings: 1098 (549 per locale)
|
||||
/// Strings: 1120 (560 per locale)
|
||||
///
|
||||
/// Built on 2024-03-20 at 22:41 UTC
|
||||
/// Built on 2024-03-24 at 14:28 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
|
@ -183,11 +183,11 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
|||
String get noRecords => 'No records';
|
||||
String noOldRecords({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||
zero: 'No records',
|
||||
one: '${n} record',
|
||||
two: '${n} records',
|
||||
few: '${n} records',
|
||||
many: '${n} records',
|
||||
other: '${n} records',
|
||||
one: 'Only ${n} record',
|
||||
two: 'Only ${n} records',
|
||||
few: 'Only ${n} records',
|
||||
many: 'Only ${n} records',
|
||||
other: 'Only ${n} records',
|
||||
);
|
||||
String get noRecord => 'No record';
|
||||
String get botRecord => 'Bots are not allowed to set records';
|
||||
|
@ -212,7 +212,7 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
|||
String supporter({required Object tier}) => 'Supporter tier ${tier}';
|
||||
String comparingWith({required Object newDate, required Object oldDate}) => 'Data from ${newDate} comparing with ${oldDate}';
|
||||
String get top => 'Top';
|
||||
String get topRank => 'Top Rank';
|
||||
String get topRank => 'Top rank';
|
||||
String verdictGeneral({required Object n, required Object verdict, required Object rank}) => '${n} ${verdict} than ${rank} rank average';
|
||||
String get verdictBetter => 'better';
|
||||
String get verdictWorse => 'worse';
|
||||
|
@ -271,10 +271,14 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
|||
String get openReplay => 'Open replay in TETR.IO';
|
||||
String replaySaved({required Object path}) => 'Replay saved to ${path}';
|
||||
String get match => 'Match';
|
||||
String get timeWeightedmatch => 'Match (time-weighted)';
|
||||
String roundNumber({required Object n}) => 'Round ${n}';
|
||||
String get statsFor => 'Stats for';
|
||||
String get numberOfRounds => 'Number of rounds';
|
||||
String get matchLength => 'Match Length';
|
||||
String get roundLength => 'Round Length';
|
||||
String get matchStats => 'Match stats';
|
||||
String get timeWeightedmatchStats => 'Time-weighted match stats';
|
||||
String get replayIssue => 'Can\'t process replay';
|
||||
String get matchIsTooOld => 'Replay is not available';
|
||||
String get winner => 'Winner';
|
||||
|
@ -311,6 +315,15 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
|||
many: '${n} players',
|
||||
other: '${n} players',
|
||||
);
|
||||
String games({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||
zero: '${n} games',
|
||||
one: '${n} game',
|
||||
two: '${n} games',
|
||||
few: '${n} games',
|
||||
many: '${n} games',
|
||||
other: '${n} games',
|
||||
);
|
||||
String gamesPlayed({required Object games}) => '${games} played';
|
||||
String get chart => 'Chart';
|
||||
String get entries => 'Entries';
|
||||
String get minimums => 'Minimums';
|
||||
|
@ -853,7 +866,7 @@ class _StringsRu implements Translations {
|
|||
@override String get assignedManualy => 'Этот значок был присвоен вручную администрацией TETR.IO';
|
||||
@override String comparingWith({required Object newDate, required Object oldDate}) => 'Данные от ${newDate} в сравнении с данными от ${oldDate}';
|
||||
@override String get top => 'Топ';
|
||||
@override String get topRank => 'Топ Ранг';
|
||||
@override String get topRank => 'Топ ранг';
|
||||
@override String verdictGeneral({required Object verdict, required Object rank, required Object n}) => '${verdict} среднего ${rank} ранга на ${n}';
|
||||
@override String get verdictBetter => 'Лучше';
|
||||
@override String get verdictWorse => 'Хуже';
|
||||
|
@ -912,10 +925,14 @@ class _StringsRu implements Translations {
|
|||
@override String get openReplay => 'Открыть повтор в TETR.IO';
|
||||
@override String replaySaved({required Object path}) => 'Повтор сохранён по пути ${path}';
|
||||
@override String get match => 'Матч';
|
||||
@override String get timeWeightedmatch => 'Матч (взвешенная по времени)';
|
||||
@override String roundNumber({required Object n}) => 'Раунд ${n}';
|
||||
@override String get statsFor => 'Статистика за';
|
||||
@override String get numberOfRounds => 'Количество раундов';
|
||||
@override String get matchLength => 'Продолжительность матча';
|
||||
@override String get roundLength => 'Продолжительность раунда';
|
||||
@override String get matchStats => 'Статистика матча';
|
||||
@override String get timeWeightedmatchStats => 'Взвешенная по времени cтатистика матча';
|
||||
@override String get replayIssue => 'Ошибка обработки повтора';
|
||||
@override String get matchIsTooOld => 'Информация о повторе недоступна';
|
||||
@override String get winner => 'Победитель';
|
||||
|
@ -952,6 +969,15 @@ class _StringsRu implements Translations {
|
|||
many: '${n} игроков',
|
||||
other: '${n} игроков',
|
||||
);
|
||||
@override String games({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||
zero: '${n} игр',
|
||||
one: '${n} игра',
|
||||
two: '${n} игры',
|
||||
few: '${n} игры',
|
||||
many: '${n} игр',
|
||||
other: '${n} игр',
|
||||
);
|
||||
@override String gamesPlayed({required Object games}) => '${games} сыграно';
|
||||
@override String get chart => 'График';
|
||||
@override String get entries => 'Список';
|
||||
@override String get minimums => 'Минимумы';
|
||||
|
@ -1457,11 +1483,11 @@ extension on Translations {
|
|||
case 'noRecords': return 'No records';
|
||||
case 'noOldRecords': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||
zero: 'No records',
|
||||
one: '${n} record',
|
||||
two: '${n} records',
|
||||
few: '${n} records',
|
||||
many: '${n} records',
|
||||
other: '${n} records',
|
||||
one: 'Only ${n} record',
|
||||
two: 'Only ${n} records',
|
||||
few: 'Only ${n} records',
|
||||
many: 'Only ${n} records',
|
||||
other: 'Only ${n} records',
|
||||
);
|
||||
case 'noRecord': return 'No record';
|
||||
case 'botRecord': return 'Bots are not allowed to set records';
|
||||
|
@ -1486,7 +1512,7 @@ extension on Translations {
|
|||
case 'supporter': return ({required Object tier}) => 'Supporter tier ${tier}';
|
||||
case 'comparingWith': return ({required Object newDate, required Object oldDate}) => 'Data from ${newDate} comparing with ${oldDate}';
|
||||
case 'top': return 'Top';
|
||||
case 'topRank': return 'Top Rank';
|
||||
case 'topRank': return 'Top rank';
|
||||
case 'verdictGeneral': return ({required Object n, required Object verdict, required Object rank}) => '${n} ${verdict} than ${rank} rank average';
|
||||
case 'verdictBetter': return 'better';
|
||||
case 'verdictWorse': return 'worse';
|
||||
|
@ -1545,10 +1571,14 @@ extension on Translations {
|
|||
case 'openReplay': return 'Open replay in TETR.IO';
|
||||
case 'replaySaved': return ({required Object path}) => 'Replay saved to ${path}';
|
||||
case 'match': return 'Match';
|
||||
case 'timeWeightedmatch': return 'Match (time-weighted)';
|
||||
case 'roundNumber': return ({required Object n}) => 'Round ${n}';
|
||||
case 'statsFor': return 'Stats for';
|
||||
case 'numberOfRounds': return 'Number of rounds';
|
||||
case 'matchLength': return 'Match Length';
|
||||
case 'roundLength': return 'Round Length';
|
||||
case 'matchStats': return 'Match stats';
|
||||
case 'timeWeightedmatchStats': return 'Time-weighted match stats';
|
||||
case 'replayIssue': return 'Can\'t process replay';
|
||||
case 'matchIsTooOld': return 'Replay is not available';
|
||||
case 'winner': return 'Winner';
|
||||
|
@ -1585,6 +1615,15 @@ extension on Translations {
|
|||
many: '${n} players',
|
||||
other: '${n} players',
|
||||
);
|
||||
case 'games': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
|
||||
zero: '${n} games',
|
||||
one: '${n} game',
|
||||
two: '${n} games',
|
||||
few: '${n} games',
|
||||
many: '${n} games',
|
||||
other: '${n} games',
|
||||
);
|
||||
case 'gamesPlayed': return ({required Object games}) => '${games} played';
|
||||
case 'chart': return 'Chart';
|
||||
case 'entries': return 'Entries';
|
||||
case 'minimums': return 'Minimums';
|
||||
|
@ -2053,7 +2092,7 @@ extension on _StringsRu {
|
|||
case 'assignedManualy': return 'Этот значок был присвоен вручную администрацией TETR.IO';
|
||||
case 'comparingWith': return ({required Object newDate, required Object oldDate}) => 'Данные от ${newDate} в сравнении с данными от ${oldDate}';
|
||||
case 'top': return 'Топ';
|
||||
case 'topRank': return 'Топ Ранг';
|
||||
case 'topRank': return 'Топ ранг';
|
||||
case 'verdictGeneral': return ({required Object verdict, required Object rank, required Object n}) => '${verdict} среднего ${rank} ранга на ${n}';
|
||||
case 'verdictBetter': return 'Лучше';
|
||||
case 'verdictWorse': return 'Хуже';
|
||||
|
@ -2112,10 +2151,14 @@ extension on _StringsRu {
|
|||
case 'openReplay': return 'Открыть повтор в TETR.IO';
|
||||
case 'replaySaved': return ({required Object path}) => 'Повтор сохранён по пути ${path}';
|
||||
case 'match': return 'Матч';
|
||||
case 'timeWeightedmatch': return 'Матч (взвешенная по времени)';
|
||||
case 'roundNumber': return ({required Object n}) => 'Раунд ${n}';
|
||||
case 'statsFor': return 'Статистика за';
|
||||
case 'numberOfRounds': return 'Количество раундов';
|
||||
case 'matchLength': return 'Продолжительность матча';
|
||||
case 'roundLength': return 'Продолжительность раунда';
|
||||
case 'matchStats': return 'Статистика матча';
|
||||
case 'timeWeightedmatchStats': return 'Взвешенная по времени cтатистика матча';
|
||||
case 'replayIssue': return 'Ошибка обработки повтора';
|
||||
case 'matchIsTooOld': return 'Информация о повторе недоступна';
|
||||
case 'winner': return 'Победитель';
|
||||
|
@ -2152,6 +2195,15 @@ extension on _StringsRu {
|
|||
many: '${n} игроков',
|
||||
other: '${n} игроков',
|
||||
);
|
||||
case 'games': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
|
||||
zero: '${n} игр',
|
||||
one: '${n} игра',
|
||||
two: '${n} игры',
|
||||
few: '${n} игры',
|
||||
many: '${n} игр',
|
||||
other: '${n} игр',
|
||||
);
|
||||
case 'gamesPlayed': return ({required Object games}) => '${games} сыграно';
|
||||
case 'chart': return 'График';
|
||||
case 'entries': return 'Список';
|
||||
case 'minimums': return 'Минимумы';
|
||||
|
|
|
@ -415,12 +415,12 @@ class TetrioService extends DB {
|
|||
// parsing data into TetraLeagueAlphaRecord objects
|
||||
for (var entry in csv){
|
||||
TetraLeagueAlphaRecord match = TetraLeagueAlphaRecord(
|
||||
replayId: entry[0],
|
||||
ownId: entry[0], // i gonna disting p1nkl0bst3r entries with it
|
||||
replayId: entry[0].toString(),
|
||||
ownId: entry[0].toString(), // i gonna disting p1nkl0bst3r entries with it
|
||||
timestamp: DateTime.parse(entry[1]),
|
||||
endContext: [
|
||||
EndContextMulti(
|
||||
userId: entry[2],
|
||||
userId: entry[2].toString(),
|
||||
username: entry[3].toString(),
|
||||
naturalOrder: 0,
|
||||
inputs: -1,
|
||||
|
@ -437,7 +437,7 @@ class TetrioService extends DB {
|
|||
success: true
|
||||
),
|
||||
EndContextMulti(
|
||||
userId: entry[8],
|
||||
userId: entry[8].toString(),
|
||||
username: entry[9].toString(),
|
||||
naturalOrder: 1,
|
||||
inputs: -1,
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
Color getColorOfRank(int rank){
|
||||
if (rank == 1) return Colors.yellowAccent;
|
||||
if (rank == 2) return Colors.blueGrey;
|
||||
if (rank == 3) return Colors.brown[400]!;
|
||||
if (rank <= 9) return Colors.blueAccent;
|
||||
if (rank <= 99) return Colors.greenAccent;
|
||||
return Colors.grey;
|
||||
}
|
|
@ -8,3 +8,4 @@ final NumberFormat f3 = NumberFormat.decimalPatternDigits(locale: LocaleSettings
|
|||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
||||
final NumberFormat f2l = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2)..minimumFractionDigits = 0;
|
||||
final NumberFormat f0 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode);
|
||||
final NumberFormat percentage = NumberFormat.percentPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
|
|
@ -66,76 +66,65 @@ class CalcState extends State<CalcView> {
|
|||
title: Text(t.statsCalc),
|
||||
),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
body: SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 768),
|
||||
child: NestedScrollView(
|
||||
controller: _scrollController,
|
||||
headerSliverBuilder: (context, value) {
|
||||
return [
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 16, 16, 32),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: TextField(
|
||||
onSubmitted: (value) => calc(),
|
||||
controller: apmController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: const InputDecoration(label: Text("APM"), alignLabelWithHint: true),
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onSubmitted: (value) => calc(),
|
||||
controller: ppsController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: const InputDecoration(label: Text("PPS"), alignLabelWithHint: true),
|
||||
)),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12),
|
||||
child: TextField(
|
||||
onSubmitted: (value) => calc(),
|
||||
controller: vsController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: const InputDecoration(label: Text("VS"), alignLabelWithHint: true),
|
||||
),
|
||||
)),
|
||||
TextButton(
|
||||
onPressed: () => calc(),
|
||||
child: Text(t.calc),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 16, 16, 32),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: TextField(
|
||||
onSubmitted: (value) => calc(),
|
||||
controller: apmController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: const InputDecoration(label: Text("APM"), alignLabelWithHint: true),
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onSubmitted: (value) => calc(),
|
||||
controller: ppsController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: const InputDecoration(label: Text("PPS"), alignLabelWithHint: true),
|
||||
)),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12),
|
||||
child: TextField(
|
||||
onSubmitted: (value) => calc(),
|
||||
controller: vsController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: const InputDecoration(label: Text("VS"), alignLabelWithHint: true),
|
||||
),
|
||||
)),
|
||||
TextButton(
|
||||
onPressed: () => calc(),
|
||||
child: Text(t.calc),
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(),
|
||||
)
|
||||
];
|
||||
},
|
||||
body: nerdStats == null
|
||||
? Text(t.calcViewNoValues)
|
||||
: ListView(
|
||||
children: [
|
||||
_ListEntry(value: nerdStats!.app, label: t.statCellNum.app.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.vsapm, label: "VS/APM", fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.dss, label: t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.dsp, label: t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.appdsp, label: "APP + DS/P", fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.cheese, label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.gbe, label: t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.nyaapp, label: t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.area, label: t.statCellNum.area.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: estTr!.esttr, label: t.statCellNum.estOfTR, fractionDigits: 3),
|
||||
Graphs(apm!, pps!, vs!, nerdStats!, playstyle!),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
if (nerdStats == null) Text(t.calcViewNoValues)
|
||||
else Column(children: [
|
||||
_ListEntry(value: nerdStats!.app, label: t.statCellNum.app.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.vsapm, label: "VS/APM", fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.dss, label: t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.dsp, label: t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.appdsp, label: "APP + DS/P", fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.cheese, label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.gbe, label: t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.nyaapp, label: t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: nerdStats!.area, label: t.statCellNum.area.replaceAll(RegExp(r'\n'), " "), fractionDigits: 3),
|
||||
_ListEntry(value: estTr!.esttr, label: t.statCellNum.estOfTR, fractionDigits: 3),
|
||||
Graphs(apm!, pps!, vs!, nerdStats!, playstyle!)
|
||||
],)
|
||||
],),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -255,452 +255,433 @@ class CompareState extends State<CompareView> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(title: Text("$titleGreenSide ${t.vs} $titleRedSide")),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
body: SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
child: Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 768),
|
||||
child: NestedScrollView(
|
||||
controller: _scrollController,
|
||||
headerSliverBuilder: (context, value) {
|
||||
return [
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.green, Colors.transparent],
|
||||
begin: Alignment.bottomCenter,
|
||||
end: Alignment.topCenter,
|
||||
stops: [0.0, 0.4],
|
||||
)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||
child: PlayerSelector(
|
||||
data: theGreenSide,
|
||||
mode: greenSideMode,
|
||||
fetch: fetchGreenSide,
|
||||
change: changeGreenSide,
|
||||
updateState: _justUpdate,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.green, Colors.transparent],
|
||||
begin: Alignment.bottomCenter,
|
||||
end: Alignment.topCenter,
|
||||
stops: [0.0, 0.4],
|
||||
)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||
child: PlayerSelector(
|
||||
data: theGreenSide,
|
||||
mode: greenSideMode,
|
||||
fetch: fetchGreenSide,
|
||||
change: changeGreenSide,
|
||||
updateState: _justUpdate,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 16),
|
||||
child: Text("VS"),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.red, Colors.transparent],
|
||||
begin: Alignment.bottomCenter,
|
||||
end: Alignment.topCenter,
|
||||
stops: [0.0, 0.4],
|
||||
)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||
child: PlayerSelector(
|
||||
data: theRedSide,
|
||||
mode: redSideMode,
|
||||
fetch: fetchRedSide,
|
||||
change: changeRedSide,
|
||||
updateState: _justUpdate,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(),
|
||||
)
|
||||
];
|
||||
},
|
||||
body: Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 768),
|
||||
child: ListView(
|
||||
children: !listEquals(theGreenSide, [null, null, null]) && !listEquals(theRedSide, [null, null, null])? [
|
||||
if (theGreenSide[0] != null &&
|
||||
theRedSide[0] != null &&
|
||||
theGreenSide[0]!.role != "banned" &&
|
||||
theRedSide[0]!.role != "banned")
|
||||
Column(
|
||||
children: [
|
||||
CompareRegTimeThingy(
|
||||
greenSide: theGreenSide[0].registrationTime,
|
||||
redSide: theRedSide[0].registrationTime,
|
||||
label: t.registred),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.level,
|
||||
greenSide: theGreenSide[0].level,
|
||||
redSide: theRedSide[0].level,
|
||||
higherIsBetter: true,
|
||||
fractionDigits: 2,
|
||||
),
|
||||
if (!theGreenSide[0].gameTime.isNegative &&
|
||||
!theRedSide[0].gameTime.isNegative)
|
||||
CompareThingy(
|
||||
greenSide: theGreenSide[0].gameTime.inMicroseconds /
|
||||
1000000 /
|
||||
60 /
|
||||
60,
|
||||
redSide: theRedSide[0].gameTime.inMicroseconds /
|
||||
1000000 /
|
||||
60 /
|
||||
60,
|
||||
label: t.statCellNum.hoursPlayed.replaceAll(RegExp(r'\n'), " "),
|
||||
higherIsBetter: true,
|
||||
fractionDigits: 2,
|
||||
),
|
||||
if (theGreenSide[0].gamesPlayed >= 0 &&
|
||||
theRedSide[0].gamesPlayed >= 0)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.onlineGames.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[0].gamesPlayed,
|
||||
redSide: theRedSide[0].gamesPlayed,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[0].gamesWon >= 0 &&
|
||||
theRedSide[0].gamesWon >= 0)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.gamesWon.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[0].gamesWon,
|
||||
redSide: theRedSide[0].gamesWon,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.friends,
|
||||
greenSide: theGreenSide[0].friendCount,
|
||||
redSide: theRedSide[0].friendCount,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
),
|
||||
if (theGreenSide[0] != null &&
|
||||
theRedSide[0] != null &&
|
||||
(theGreenSide[0]!.role == "banned" ||
|
||||
theRedSide[0]!.role == "banned"))
|
||||
CompareBoolThingy(
|
||||
greenSide: theGreenSide[0].role == "banned",
|
||||
redSide: theRedSide[0].role == "banned",
|
||||
label: t.normalBanned,
|
||||
trueIsBetter: false),
|
||||
(theGreenSide[2].gamesPlayed > 0 || greenSideMode == Mode.stats) &&
|
||||
(theRedSide[2].gamesPlayed > 0 || redSideMode == Mode.stats)
|
||||
? Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Text(t.tetraLeague,
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: bigScreen ? 42 : 28)),
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theRedSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "TR",
|
||||
greenSide: theGreenSide[2].rating,
|
||||
redSide: theRedSide[2].rating,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[2].gamesPlayed,
|
||||
redSide: theRedSide[2].gamesPlayed,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.gamesWonTL.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[2].gamesWon,
|
||||
redSide: theRedSide[2].gamesWon,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "WR %",
|
||||
greenSide:
|
||||
theGreenSide[2].winrate * 100,
|
||||
redSide: theRedSide[2].winrate * 100,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theRedSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "Glicko",
|
||||
greenSide: theGreenSide[2].glicko!,
|
||||
redSide: theRedSide[2].glicko!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theRedSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "RD",
|
||||
greenSide: theGreenSide[2].rd!,
|
||||
redSide: theRedSide[2].rd!,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: false,
|
||||
),
|
||||
if (theGreenSide[2].standing > 0 &&
|
||||
theRedSide[2].standing > 0 &&
|
||||
greenSideMode == Mode.player &&
|
||||
redSideMode == Mode.player)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.lbpShort,
|
||||
greenSide: theGreenSide[2].standing,
|
||||
redSide: theRedSide[2].standing,
|
||||
higherIsBetter: false,
|
||||
),
|
||||
if (theGreenSide[2].standingLocal > 0 &&
|
||||
theRedSide[2].standingLocal > 0 &&
|
||||
greenSideMode == Mode.player &&
|
||||
redSideMode == Mode.player)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.lbpcShort,
|
||||
greenSide:
|
||||
theGreenSide[2].standingLocal,
|
||||
redSide: theRedSide[2].standingLocal,
|
||||
higherIsBetter: false,
|
||||
),
|
||||
if (theGreenSide[2].apm != null &&
|
||||
theRedSide[2].apm != null)
|
||||
CompareThingy(
|
||||
label: "APM",
|
||||
greenSide: theGreenSide[2].apm!,
|
||||
redSide: theRedSide[2].apm!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].pps != null &&
|
||||
theRedSide[2].pps != null)
|
||||
CompareThingy(
|
||||
label: "PPS",
|
||||
greenSide: theGreenSide[2].pps!,
|
||||
redSide: theRedSide[2].pps!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].vs != null &&
|
||||
theRedSide[2].vs != null)
|
||||
CompareThingy(
|
||||
label: "VS",
|
||||
greenSide: theGreenSide[2].vs!,
|
||||
redSide: theRedSide[2].vs!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
],
|
||||
)
|
||||
: CompareBoolThingy(
|
||||
greenSide: theGreenSide[2].gamesPlayed > 0,
|
||||
redSide: theRedSide[2].gamesPlayed > 0,
|
||||
label: t.playedTL,
|
||||
trueIsBetter: false),
|
||||
const Divider(),
|
||||
if (theGreenSide[2].nerdStats != null &&
|
||||
theRedSide[2].nerdStats != null)
|
||||
Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Text(t.nerdStats,
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: bigScreen ? 42 : 28)),
|
||||
),
|
||||
CompareThingy(
|
||||
label: "APP",
|
||||
greenSide: theGreenSide[2].nerdStats!.app,
|
||||
redSide: theRedSide[2].nerdStats!.app,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "VS/APM",
|
||||
greenSide: theGreenSide[2].nerdStats!.vsapm,
|
||||
redSide: theRedSide[2].nerdStats!.vsapm,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "DS/S",
|
||||
greenSide: theGreenSide[2].nerdStats!.dss,
|
||||
redSide: theRedSide[2].nerdStats!.dss,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "DS/P",
|
||||
greenSide: theGreenSide[2].nerdStats!.dsp,
|
||||
redSide: theRedSide[2].nerdStats!.dsp,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "APP + DS/P",
|
||||
greenSide:
|
||||
theGreenSide[2].nerdStats!.appdsp,
|
||||
redSide: theRedSide[2].nerdStats!.appdsp,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide:
|
||||
theGreenSide[2].nerdStats!.cheese,
|
||||
redSide: theRedSide[2].nerdStats!.cheese,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Gb Eff.",
|
||||
greenSide: theGreenSide[2].nerdStats!.gbe,
|
||||
redSide: theRedSide[2].nerdStats!.gbe,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "wAPP",
|
||||
greenSide:
|
||||
theGreenSide[2].nerdStats!.nyaapp,
|
||||
redSide: theRedSide[2].nerdStats!.nyaapp,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Area",
|
||||
greenSide: theGreenSide[2].nerdStats!.area,
|
||||
redSide: theRedSide[2].nerdStats!.area,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.estOfTRShort,
|
||||
greenSide: theGreenSide[2].estTr!.esttr,
|
||||
redSide: theRedSide[2].estTr!.esttr,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theGreenSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.accOfEstShort,
|
||||
greenSide: theGreenSide[2].esttracc!,
|
||||
redSide: theRedSide[2].esttracc!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Opener",
|
||||
greenSide: theGreenSide[2].playstyle!.opener,
|
||||
redSide: theRedSide[2].playstyle!.opener,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Plonk",
|
||||
greenSide: theGreenSide[2].playstyle!.plonk,
|
||||
redSide: theRedSide[2].playstyle!.plonk,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Stride",
|
||||
greenSide: theGreenSide[2].playstyle!.stride,
|
||||
redSide: theRedSide[2].playstyle!.stride,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Inf. DS",
|
||||
greenSide: theGreenSide[2].playstyle!.infds,
|
||||
redSide: theRedSide[2].playstyle!.infds,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
VsGraphs(theGreenSide[2].apm!, theGreenSide[2].pps!, theGreenSide[2].vs!, theGreenSide[2].nerdStats!, theGreenSide[2].playstyle!, theRedSide[2].apm!, theRedSide[2].pps!, theRedSide[2].vs!, theRedSide[2].nerdStats!, theRedSide[2].playstyle!),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Text(t.winChance,
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: bigScreen ? 42 : 28)),
|
||||
),
|
||||
if (greenSideMode != Mode.stats && redSideMode != Mode.stats &&
|
||||
theGreenSide[2].gamesPlayed > 9 && theRedSide[2].gamesPlayed > 9)
|
||||
CompareThingy(
|
||||
label: t.byGlicko,
|
||||
greenSide: getWinrateByTR(
|
||||
theGreenSide[2].glicko!,
|
||||
theGreenSide[2].rd!,
|
||||
theRedSide[2].glicko!,
|
||||
theRedSide[2].rd!) *
|
||||
100,
|
||||
redSide: getWinrateByTR(
|
||||
theRedSide[2].glicko!,
|
||||
theRedSide[2].rd!,
|
||||
theGreenSide[2].glicko!,
|
||||
theGreenSide[2].rd!) *
|
||||
100,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
postfix: "%",
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.byEstTR,
|
||||
greenSide: getWinrateByTR(
|
||||
theGreenSide[2].estTr!.estglicko,
|
||||
theGreenSide[2].rd ?? noTrRd,
|
||||
theRedSide[2].estTr!.estglicko,
|
||||
theRedSide[2].rd ?? noTrRd) *
|
||||
100,
|
||||
redSide: getWinrateByTR(
|
||||
theRedSide[2].estTr!.estglicko,
|
||||
theRedSide[2].rd ?? noTrRd,
|
||||
theGreenSide[2].estTr!.estglicko,
|
||||
theGreenSide[2].rd ?? noTrRd) *
|
||||
100,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
postfix: "%",
|
||||
),
|
||||
],
|
||||
)
|
||||
] : [Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(t.compareViewNoValues(avgR: "\$avgR"), textAlign: TextAlign.center),
|
||||
)], // This is so fucked up holy shit
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 16),
|
||||
child: Text("VS"),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.red, Colors.transparent],
|
||||
begin: Alignment.bottomCenter,
|
||||
end: Alignment.topCenter,
|
||||
stops: [0.0, 0.4],
|
||||
)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||
child: PlayerSelector(
|
||||
data: theRedSide,
|
||||
mode: redSideMode,
|
||||
fetch: fetchRedSide,
|
||||
change: changeRedSide,
|
||||
updateState: _justUpdate,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
Divider(),
|
||||
if (!listEquals(theGreenSide, [null, null, null]) && !listEquals(theRedSide, [null, null, null])) Column(
|
||||
children: [
|
||||
if (theGreenSide[0] != null && theRedSide[0] != null && theGreenSide[0]!.role != "banned" && theRedSide[0]!.role != "banned")
|
||||
Column(
|
||||
children: [
|
||||
CompareRegTimeThingy(
|
||||
greenSide: theGreenSide[0].registrationTime,
|
||||
redSide: theRedSide[0].registrationTime,
|
||||
label: t.registred),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.level,
|
||||
greenSide: theGreenSide[0].level,
|
||||
redSide: theRedSide[0].level,
|
||||
higherIsBetter: true,
|
||||
fractionDigits: 2,
|
||||
),
|
||||
if (!theGreenSide[0].gameTime.isNegative && !theRedSide[0].gameTime.isNegative)
|
||||
CompareThingy(
|
||||
greenSide: theGreenSide[0].gameTime.inMicroseconds /
|
||||
1000000 /
|
||||
60 /
|
||||
60,
|
||||
redSide: theRedSide[0].gameTime.inMicroseconds /
|
||||
1000000 /
|
||||
60 /
|
||||
60,
|
||||
label: t.statCellNum.hoursPlayed.replaceAll(RegExp(r'\n'), " "),
|
||||
higherIsBetter: true,
|
||||
fractionDigits: 2,
|
||||
),
|
||||
if (theGreenSide[0].gamesPlayed >= 0 && theRedSide[0].gamesPlayed >= 0)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.onlineGames.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[0].gamesPlayed,
|
||||
redSide: theRedSide[0].gamesPlayed,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[0].gamesWon >= 0 && theRedSide[0].gamesWon >= 0)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.gamesWon.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[0].gamesWon,
|
||||
redSide: theRedSide[0].gamesWon,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.friends,
|
||||
greenSide: theGreenSide[0].friendCount,
|
||||
redSide: theRedSide[0].friendCount,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
),
|
||||
if (theGreenSide[0] != null && theRedSide[0] != null && (theGreenSide[0]!.role == "banned" || theRedSide[0]!.role == "banned"))
|
||||
CompareBoolThingy(
|
||||
greenSide: theGreenSide[0].role == "banned",
|
||||
redSide: theRedSide[0].role == "banned",
|
||||
label: t.normalBanned,
|
||||
trueIsBetter: false
|
||||
),
|
||||
(theGreenSide[2].gamesPlayed > 0 || greenSideMode == Mode.stats) && (theRedSide[2].gamesPlayed > 0 || redSideMode == Mode.stats)
|
||||
? Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Text(t.tetraLeague,
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: bigScreen ? 42 : 28)),
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theRedSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "TR",
|
||||
greenSide: theGreenSide[2].rating,
|
||||
redSide: theRedSide[2].rating,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[2].gamesPlayed,
|
||||
redSide: theRedSide[2].gamesPlayed,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.gamesWonTL.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide: theGreenSide[2].gamesWon,
|
||||
redSide: theRedSide[2].gamesWon,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "WR %",
|
||||
greenSide:
|
||||
theGreenSide[2].winrate * 100,
|
||||
redSide: theRedSide[2].winrate * 100,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theRedSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "Glicko",
|
||||
greenSide: theGreenSide[2].glicko!,
|
||||
redSide: theRedSide[2].glicko!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theRedSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: "RD",
|
||||
greenSide: theGreenSide[2].rd!,
|
||||
redSide: theRedSide[2].rd!,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: false,
|
||||
),
|
||||
if (theGreenSide[2].standing > 0 &&
|
||||
theRedSide[2].standing > 0 &&
|
||||
greenSideMode == Mode.player &&
|
||||
redSideMode == Mode.player)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.lbpShort,
|
||||
greenSide: theGreenSide[2].standing,
|
||||
redSide: theRedSide[2].standing,
|
||||
higherIsBetter: false,
|
||||
),
|
||||
if (theGreenSide[2].standingLocal > 0 &&
|
||||
theRedSide[2].standingLocal > 0 &&
|
||||
greenSideMode == Mode.player &&
|
||||
redSideMode == Mode.player)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.lbpcShort,
|
||||
greenSide:
|
||||
theGreenSide[2].standingLocal,
|
||||
redSide: theRedSide[2].standingLocal,
|
||||
higherIsBetter: false,
|
||||
),
|
||||
if (theGreenSide[2].apm != null &&
|
||||
theRedSide[2].apm != null)
|
||||
CompareThingy(
|
||||
label: "APM",
|
||||
greenSide: theGreenSide[2].apm!,
|
||||
redSide: theRedSide[2].apm!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].pps != null &&
|
||||
theRedSide[2].pps != null)
|
||||
CompareThingy(
|
||||
label: "PPS",
|
||||
greenSide: theGreenSide[2].pps!,
|
||||
redSide: theRedSide[2].pps!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].vs != null &&
|
||||
theRedSide[2].vs != null)
|
||||
CompareThingy(
|
||||
label: "VS",
|
||||
greenSide: theGreenSide[2].vs!,
|
||||
redSide: theRedSide[2].vs!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
],
|
||||
)
|
||||
: CompareBoolThingy(
|
||||
greenSide: theGreenSide[2].gamesPlayed > 0,
|
||||
redSide: theRedSide[2].gamesPlayed > 0,
|
||||
label: t.playedTL,
|
||||
trueIsBetter: false),
|
||||
const Divider(),
|
||||
if (theGreenSide[2].nerdStats != null &&
|
||||
theRedSide[2].nerdStats != null)
|
||||
Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Text(t.nerdStats,
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: bigScreen ? 42 : 28)),
|
||||
),
|
||||
CompareThingy(
|
||||
label: "APP",
|
||||
greenSide: theGreenSide[2].nerdStats!.app,
|
||||
redSide: theRedSide[2].nerdStats!.app,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "VS/APM",
|
||||
greenSide: theGreenSide[2].nerdStats!.vsapm,
|
||||
redSide: theRedSide[2].nerdStats!.vsapm,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "DS/S",
|
||||
greenSide: theGreenSide[2].nerdStats!.dss,
|
||||
redSide: theRedSide[2].nerdStats!.dss,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "DS/P",
|
||||
greenSide: theGreenSide[2].nerdStats!.dsp,
|
||||
redSide: theRedSide[2].nerdStats!.dsp,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "APP + DS/P",
|
||||
greenSide:
|
||||
theGreenSide[2].nerdStats!.appdsp,
|
||||
redSide: theRedSide[2].nerdStats!.appdsp,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "),
|
||||
greenSide:
|
||||
theGreenSide[2].nerdStats!.cheese,
|
||||
redSide: theRedSide[2].nerdStats!.cheese,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Gb Eff.",
|
||||
greenSide: theGreenSide[2].nerdStats!.gbe,
|
||||
redSide: theRedSide[2].nerdStats!.gbe,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "wAPP",
|
||||
greenSide:
|
||||
theGreenSide[2].nerdStats!.nyaapp,
|
||||
redSide: theRedSide[2].nerdStats!.nyaapp,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Area",
|
||||
greenSide: theGreenSide[2].nerdStats!.area,
|
||||
redSide: theRedSide[2].nerdStats!.area,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.estOfTRShort,
|
||||
greenSide: theGreenSide[2].estTr!.esttr,
|
||||
redSide: theRedSide[2].estTr!.esttr,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (theGreenSide[2].gamesPlayed > 9 &&
|
||||
theGreenSide[2].gamesPlayed > 9 &&
|
||||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.accOfEstShort,
|
||||
greenSide: theGreenSide[2].esttracc!,
|
||||
redSide: theRedSide[2].esttracc!,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Opener",
|
||||
greenSide: theGreenSide[2].playstyle!.opener,
|
||||
redSide: theRedSide[2].playstyle!.opener,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Plonk",
|
||||
greenSide: theGreenSide[2].playstyle!.plonk,
|
||||
redSide: theRedSide[2].playstyle!.plonk,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Stride",
|
||||
greenSide: theGreenSide[2].playstyle!.stride,
|
||||
redSide: theRedSide[2].playstyle!.stride,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: "Inf. DS",
|
||||
greenSide: theGreenSide[2].playstyle!.infds,
|
||||
redSide: theRedSide[2].playstyle!.infds,
|
||||
fractionDigits: 3,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
VsGraphs(theGreenSide[2].apm!, theGreenSide[2].pps!, theGreenSide[2].vs!, theGreenSide[2].nerdStats!, theGreenSide[2].playstyle!, theRedSide[2].apm!, theRedSide[2].pps!, theRedSide[2].vs!, theRedSide[2].nerdStats!, theRedSide[2].playstyle!),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Text(t.winChance,
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: bigScreen ? 42 : 28)),
|
||||
),
|
||||
if (greenSideMode != Mode.stats && redSideMode != Mode.stats &&
|
||||
theGreenSide[2].gamesPlayed > 9 && theRedSide[2].gamesPlayed > 9)
|
||||
CompareThingy(
|
||||
label: t.byGlicko,
|
||||
greenSide: getWinrateByTR(
|
||||
theGreenSide[2].glicko!,
|
||||
theGreenSide[2].rd!,
|
||||
theRedSide[2].glicko!,
|
||||
theRedSide[2].rd!) *
|
||||
100,
|
||||
redSide: getWinrateByTR(
|
||||
theRedSide[2].glicko!,
|
||||
theRedSide[2].rd!,
|
||||
theGreenSide[2].glicko!,
|
||||
theGreenSide[2].rd!) *
|
||||
100,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
postfix: "%",
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.byEstTR,
|
||||
greenSide: getWinrateByTR(
|
||||
theGreenSide[2].estTr!.estglicko,
|
||||
theGreenSide[2].rd ?? noTrRd,
|
||||
theRedSide[2].estTr!.estglicko,
|
||||
theRedSide[2].rd ?? noTrRd) *
|
||||
100,
|
||||
redSide: getWinrateByTR(
|
||||
theRedSide[2].estTr!.estglicko,
|
||||
theRedSide[2].rd ?? noTrRd,
|
||||
theGreenSide[2].estTr!.estglicko,
|
||||
theGreenSide[2].rd ?? noTrRd) *
|
||||
100,
|
||||
fractionDigits: 2,
|
||||
higherIsBetter: true,
|
||||
postfix: "%",
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
else Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(t.compareViewNoValues(avgR: "\$avgR"), textAlign: TextAlign.center),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -34,7 +34,7 @@ import 'package:go_router/go_router.dart';
|
|||
|
||||
final TetrioService teto = TetrioService(); // thing, that manadge our local DB
|
||||
int _chartsIndex = 0;
|
||||
bool _showHistoryAsTable = false;
|
||||
bool _gamesPlayedInsteadOfDateAndTime = false;
|
||||
List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR", "Opener", "Plonk", "Inf. DS", "Stride"];
|
||||
late ScrollController _scrollController;
|
||||
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
||||
|
@ -85,6 +85,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
String _titleNickname = "dan63047";
|
||||
/// Each dropdown menu item contains list of dots for the graph
|
||||
var chartsData = <DropdownMenuItem<List<FlSpot>>>[];
|
||||
var chartsDataGamesPlayed = <DropdownMenuItem<List<FlSpot>>>[];
|
||||
//var tableData = <TableRow>[];
|
||||
final bodyGlobalKey = GlobalKey();
|
||||
bool _showSearchBar = false;
|
||||
|
@ -283,6 +284,29 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.infds)], child: const Text("Inf. DS")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.stride)], child: const Text("Stride")),
|
||||
];
|
||||
chartsDataGamesPlayed = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.glicko!)], child: const Text("Glicko")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.gamesPlayed.toDouble(), tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.gamesPlayed.toDouble(), tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.gamesPlayed.toDouble(), tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.gamesPlayed.toDouble(), tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.gamesPlayed.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.opener)], child: const Text("Opener")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.plonk)], child: const Text("Plonk")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.infds)], child: const Text("Inf. DS")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.stride)], child: const Text("Stride")),
|
||||
];
|
||||
}else{
|
||||
compareWith = null;
|
||||
chartsData = [];
|
||||
|
@ -393,8 +417,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
return notification.depth == 0;
|
||||
},
|
||||
child: NestedScrollView(
|
||||
scrollBehavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
scrollBehavior: ScrollConfiguration.of(context).copyWith(scrollbars: false, physics: const AlwaysScrollableScrollPhysics()),
|
||||
controller: _scrollController,
|
||||
headerSliverBuilder: (context, value) {
|
||||
return [
|
||||
|
@ -448,10 +471,10 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
),
|
||||
SizedBox(
|
||||
width: 450,
|
||||
child: _TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched)
|
||||
child: _TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true,)
|
||||
),
|
||||
],),
|
||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||
_History(chartsData: chartsData, chartsDataGamesPlayed: chartsDataGamesPlayed, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||
_TwoRecordsThingy(sprint: snapshot.data![1]['sprint'], blitz: 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],)
|
||||
] : [
|
||||
|
@ -466,7 +489,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
lbPositions: meAmongEveryone
|
||||
),
|
||||
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched),
|
||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||
_History(chartsData: chartsData, chartsDataGamesPlayed: chartsDataGamesPlayed, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
||||
_RecordThingy(record: snapshot.data![1]['sprint'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
||||
_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],)
|
||||
|
@ -664,10 +687,11 @@ class _TLRecords extends StatelessWidget {
|
|||
final List<TetraLeagueAlphaRecord> data;
|
||||
final bool wasActiveInTL;
|
||||
final bool oldMathcesHere;
|
||||
final bool separateScrollController;
|
||||
|
||||
/// Widget, that displays Tetra League records.
|
||||
/// Accepts list of TL records ([data]) and [userID] of player from the view
|
||||
const _TLRecords({required this.userID, required this.changePlayer, required this.data, required this.wasActiveInTL, required this.oldMathcesHere});
|
||||
const _TLRecords({required this.userID, required this.changePlayer, required this.data, required this.wasActiveInTL, required this.oldMathcesHere, this.separateScrollController = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -685,7 +709,7 @@ class _TLRecords extends StatelessWidget {
|
|||
int length = data.length;
|
||||
return ListView.builder(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: ScrollController(),
|
||||
controller: separateScrollController ? ScrollController() : null,
|
||||
itemCount: oldMathcesHere ? length : length + 1,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (index == length) {
|
||||
|
@ -708,7 +732,6 @@ class _TLRecords extends StatelessWidget {
|
|||
)
|
||||
),
|
||||
child: ListTile(
|
||||
// tileColor: data[index].endContext.firstWhere((element) => element.userId == userID).success ? Colors.green[900] : Colors.red[900],
|
||||
leading: Text("${data[index].endContext.firstWhere((element) => element.userId == userID).points} : ${data[index].endContext.firstWhere((element) => element.userId != userID).points}",
|
||||
style: bigScreen ? const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, shadows: textShadow) : const TextStyle(fontSize: 28, shadows: textShadow)),
|
||||
title: Text("vs. ${data[index].endContext.firstWhere((element) => element.userId != userID).username}"),
|
||||
|
@ -730,6 +753,7 @@ class _TLRecords extends StatelessWidget {
|
|||
|
||||
class _History extends StatelessWidget{
|
||||
final List<DropdownMenuItem<List<FlSpot>>> chartsData;
|
||||
final List<DropdownMenuItem<List<FlSpot>>> chartsDataGamesPlayed;
|
||||
final String userID;
|
||||
final Function update;
|
||||
final Function changePlayer;
|
||||
|
@ -737,7 +761,7 @@ class _History extends StatelessWidget{
|
|||
|
||||
/// Widget, that can show history of some stat of the player on the graph.
|
||||
/// Requires player [states], which is list of states and function [update], which rebuild widgets
|
||||
const _History({required this.chartsData, required this.userID, required this.changePlayer, required this.update, required this.wasActiveInTL});
|
||||
const _History({required this.chartsData, required this.chartsDataGamesPlayed, required this.userID, required this.changePlayer, required this.update, required this.wasActiveInTL});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -763,15 +787,25 @@ class _History extends StatelessWidget{
|
|||
Wrap(
|
||||
spacing: 20,
|
||||
children: [
|
||||
// DropdownButton(
|
||||
// items: [DropdownMenuItem(child: Text("Chart"), value: false), DropdownMenuItem(child: Text("Table"), value: true)],
|
||||
// value: _showHistoryAsTable,
|
||||
// onChanged: (value) {
|
||||
// _showHistoryAsTable = value!;
|
||||
// update();
|
||||
// }
|
||||
// ),
|
||||
DropdownButton(
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Padding(padding: EdgeInsets.all(8.0), child: Text("X:", style: TextStyle(fontSize: 22))),
|
||||
DropdownButton(
|
||||
items: const [DropdownMenuItem(value: false, child: Text("Date & Time")), DropdownMenuItem(value: true, child: Text("Games Played"))],
|
||||
value: _gamesPlayedInsteadOfDateAndTime,
|
||||
onChanged: (value) {
|
||||
_gamesPlayedInsteadOfDateAndTime = value!;
|
||||
update();
|
||||
}
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Padding(padding: EdgeInsets.all(8.0), child: Text("Y:", style: TextStyle(fontSize: 22))),
|
||||
DropdownButton(
|
||||
items: chartsData,
|
||||
value: chartsData[_chartsIndex].value,
|
||||
onChanged: (value) {
|
||||
|
@ -779,10 +813,12 @@ class _History extends StatelessWidget{
|
|||
update();
|
||||
}
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
if(chartsData[_chartsIndex].value!.length > 1 && !_showHistoryAsTable) _HistoryChartThigy(data: chartsData[_chartsIndex].value!, yAxisTitle: _historyShortTitles[_chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? f2 : NumberFormat.compact(),)
|
||||
else if (chartsData[_chartsIndex].value!.length <= 1 && !_showHistoryAsTable) Center(child: Column(
|
||||
if(chartsData[_chartsIndex].value!.length > 1) _HistoryChartThigy(data: _gamesPlayedInsteadOfDateAndTime ? chartsDataGamesPlayed[_chartsIndex].value! : chartsData[_chartsIndex].value!, yAxisTitle: _historyShortTitles[_chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? f2 : NumberFormat.compact(), xFormat: NumberFormat.compact())
|
||||
else if (chartsData[_chartsIndex].value!.length <= 1) Center(child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(t.notEnoughData, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)),
|
||||
|
@ -790,10 +826,6 @@ class _History extends StatelessWidget{
|
|||
if (wasActiveInTL) TextButton(onPressed: (){changePlayer(userID, fetchHistory: true);}, child: Text(t.fetchAndsaveTLHistory))
|
||||
],
|
||||
))
|
||||
// else if (_showHistoryAsTable) Padding(
|
||||
// padding: const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0),
|
||||
// child: _HistoryTableThingy(tableData),
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -807,11 +839,12 @@ class _HistoryChartThigy extends StatefulWidget{
|
|||
final bool bigScreen;
|
||||
final double leftSpace;
|
||||
final NumberFormat yFormat;
|
||||
final NumberFormat? xFormat;
|
||||
|
||||
/// Implements graph for the _History widget. Requires [data] which is a list of dots for the graph. [yAxisTitle] used to keep track of changes.
|
||||
/// [bigScreen] tells if screen wide enough, [leftSpace] sets size, reserved for titles on the left from the graph and [yFormat] sets number format
|
||||
/// for left titles
|
||||
const _HistoryChartThigy({required this.data, required this.yAxisTitle, required this.bigScreen, required this.leftSpace, required this.yFormat});
|
||||
const _HistoryChartThigy({required this.data, required this.yAxisTitle, required this.bigScreen, required this.leftSpace, required this.yFormat, this.xFormat});
|
||||
|
||||
@override
|
||||
State<_HistoryChartThigy> createState() => _HistoryChartThigyState();
|
||||
|
@ -819,6 +852,7 @@ class _HistoryChartThigy extends StatefulWidget{
|
|||
|
||||
class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
||||
late String previousAxisTitle;
|
||||
late bool previousGamesPlayedInsteadOfDateAndTime;
|
||||
late double minX;
|
||||
late double maxX;
|
||||
late double minY;
|
||||
|
@ -840,6 +874,7 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
|||
maxX = widget.data.last.x;
|
||||
setMinMaxY();
|
||||
previousAxisTitle = widget.yAxisTitle;
|
||||
previousGamesPlayedInsteadOfDateAndTime = _gamesPlayedInsteadOfDateAndTime;
|
||||
actualMaxY = maxY;
|
||||
actualMinY = minY;
|
||||
recalculateScales();
|
||||
|
@ -945,15 +980,19 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
GlobalKey graphKey = GlobalKey();
|
||||
double xInterval = widget.bigScreen ? max(1, xScale / 6) : max(1, xScale / 3); // how far away xTitles should be between each other
|
||||
if ((previousAxisTitle != widget.yAxisTitle) || (previousGamesPlayedInsteadOfDateAndTime != _gamesPlayedInsteadOfDateAndTime)) {
|
||||
minX = widget.data.first.x;
|
||||
maxX = widget.data.last.x;
|
||||
recalculateScales();
|
||||
setMinMaxY();
|
||||
previousAxisTitle = widget.yAxisTitle;
|
||||
previousGamesPlayedInsteadOfDateAndTime = _gamesPlayedInsteadOfDateAndTime;
|
||||
setState((){});
|
||||
}
|
||||
double xInterval = widget.bigScreen ? max(1, xScale / 8) : max(1, xScale / 4); // how far away xTitles should be between each other
|
||||
EdgeInsets padding = widget.bigScreen ? const EdgeInsets.fromLTRB(40, 30, 40, 30) : const EdgeInsets.fromLTRB(0, 40, 16, 48);
|
||||
double graphStartX = padding.left+widget.leftSpace;
|
||||
double graphEndX = MediaQuery.sizeOf(context).width - padding.right;
|
||||
if (previousAxisTitle != widget.yAxisTitle) {
|
||||
setMinMaxY();
|
||||
recalculateScales();
|
||||
previousAxisTitle = widget.yAxisTitle;
|
||||
}
|
||||
return SizedBox(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height - 104,
|
||||
|
@ -1025,7 +1064,7 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
|||
bottomTitles: AxisTitles(sideTitles: SideTitles(interval: xInterval, showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){
|
||||
return value != meta.min && value != meta.max ? SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
child: Text(DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))),
|
||||
child: Text(widget.xFormat != null && _gamesPlayedInsteadOfDateAndTime ? widget.xFormat!.format(value.round()) : DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))),
|
||||
) : Container();
|
||||
})),
|
||||
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: widget.leftSpace, getTitlesWidget: (double value, TitleMeta meta){
|
||||
|
@ -1048,7 +1087,7 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
|||
} else {
|
||||
hoveredPointId = touchResponse!.lineBarSpots!.first.spotIndex;
|
||||
headerTooltip = "${f4.format(touchResponse.lineBarSpots!.first.y)} ${widget.yAxisTitle}";
|
||||
footerTooltip = _dateFormat.format(DateTime.fromMillisecondsSinceEpoch(touchResponse.lineBarSpots!.first.x.floor()));
|
||||
footerTooltip = _gamesPlayedInsteadOfDateAndTime ? "${f0.format(touchResponse.lineBarSpots!.first.x)} games played" : _dateFormat.format(DateTime.fromMillisecondsSinceEpoch(touchResponse.lineBarSpots!.first.x.floor()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1207,7 +1246,7 @@ class _TwoRecordsThingy extends StatelessWidget {
|
|||
RichText(
|
||||
text: TextSpan(
|
||||
text: "",
|
||||
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: FontWeight.w500),
|
||||
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
|
||||
children: [
|
||||
TextSpan(text: blitz != null ? NumberFormat.decimalPattern().format(blitz!.endContext!.score) : "---"),
|
||||
//WidgetSpan(child: Image.asset("res/icons/kagari.png", height: 48))
|
||||
|
@ -1295,6 +1334,7 @@ class _RecordThingy extends StatelessWidget {
|
|||
builder: (context, constraints) {
|
||||
bool bigScreen = constraints.maxWidth > 768;
|
||||
return SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Column(
|
||||
|
|
|
@ -54,7 +54,8 @@ class RanksAverages extends State<RankAveragesView> {
|
|||
return ListTile(
|
||||
leading: Image.asset("res/tetrio_tl_alpha_ranks/${keys[index]}.png", height: 48),
|
||||
title: Text(t.players(n: averages[keys[index]]?[1]["players"]), style: const TextStyle(fontFamily: "Eurostile Round Extended")),
|
||||
subtitle: Text("${f2.format(averages[keys[index]]?[0].apm)} APM, ${f2.format(averages[keys[index]]?[0].pps)} PPS, ${f2.format(averages[keys[index]]?[0].vs)} VS, ${f2.format(averages[keys[index]]?[0].nerdStats.app)} APP, ${f2.format(averages[keys[index]]?[0].nerdStats.vsapm)} VS/APM"),
|
||||
subtitle: Text("${f2.format(averages[keys[index]]?[0].apm)} APM, ${f2.format(averages[keys[index]]?[0].pps)} PPS, ${f2.format(averages[keys[index]]?[0].vs)} VS, ${f2.format(averages[keys[index]]?[0].nerdStats.app)} APP, ${f2.format(averages[keys[index]]?[0].nerdStats.vsapm)} VS/APM",
|
||||
style: TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey)),
|
||||
trailing: Text("${f2.format(averages[keys[index]]?[1]["toEnterTR"])} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null),
|
||||
onTap: (){
|
||||
if (averages[keys[index]]?[1]["players"] > 0) {
|
||||
|
|
|
@ -175,7 +175,8 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
|||
return ListTile(
|
||||
leading: Text((index+1).toString(), style: bigScreen ? const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28) : null),
|
||||
title: Text(allPlayers[index].username, style: const TextStyle(fontFamily: "Eurostile Round Extended")),
|
||||
subtitle: Text(_sortBy == Stats.tr ? "${f2.format(allPlayers[index].apm)} APM, ${f2.format(allPlayers[index].pps)} PPS, ${f2.format(allPlayers[index].vs)} VS, ${f2.format(allPlayers[index].nerdStats.app)} APP, ${f2.format(allPlayers[index].nerdStats.vsapm)} VS/APM" : "${_f4.format(allPlayers[index].getStatByEnum(_sortBy))} ${chartsShortTitles[_sortBy]}"),
|
||||
subtitle: Text(_sortBy == Stats.tr ? "${f2.format(allPlayers[index].apm)} APM, ${f2.format(allPlayers[index].pps)} PPS, ${f2.format(allPlayers[index].vs)} VS, ${f2.format(allPlayers[index].nerdStats.app)} APP, ${f2.format(allPlayers[index].nerdStats.vsapm)} VS/APM" : "${_f4.format(allPlayers[index].getStatByEnum(_sortBy))} ${chartsShortTitles[_sortBy]}",
|
||||
style: TextStyle(fontFamily: "Eurostile Round Condensed", color: _sortBy == Stats.tr ? Colors.grey : null)),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
|
|
|
@ -70,7 +70,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
timeWeightedStatsAvaliable = true;
|
||||
if (snapshot.connectionState != ConnectionState.done) return const LinearProgressIndicator();
|
||||
if (!snapshot.hasError){
|
||||
if (rounds.indexWhere((element) => element.value == -2) == -1) rounds.insert(1, const DropdownMenuItem(value: -2, child: Text("timeWeightedStats")));
|
||||
if (rounds.indexWhere((element) => element.value == -2) == -1) rounds.insert(1, DropdownMenuItem(value: -2, child: Text(t.timeWeightedmatch)));
|
||||
greenSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId == widget.initPlayerId);
|
||||
redSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId != widget.initPlayerId);
|
||||
if (roundSelector.isNegative){
|
||||
|
@ -81,7 +81,6 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
readableTime = "${t.roundLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}\n${t.winner}: ${snapshot.data!.roundWinners[roundSelector][1]}";
|
||||
}
|
||||
}else{
|
||||
timeWeightedStatsAvaliable = false;
|
||||
switch (snapshot.error.runtimeType){
|
||||
case ReplayNotAvalable:
|
||||
reason = t.matchIsTooOld;
|
||||
|
@ -509,7 +508,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
RichText(
|
||||
text: TextSpan(
|
||||
text: "${time.inMinutes}:${NumberFormat("00", LocaleSettings.currentLocale.languageCode).format(time.inSeconds%60)}",
|
||||
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, fontWeight: FontWeight.w500),
|
||||
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, fontWeight: FontWeight.w500, color: Colors.white),
|
||||
children: [TextSpan(text: ".${NumberFormat("000", LocaleSettings.currentLocale.languageCode).format(time.inMilliseconds%1000)}", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))]
|
||||
),
|
||||
)
|
||||
|
@ -533,6 +532,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
reason = snapshot.error.toString();
|
||||
break;
|
||||
}
|
||||
timeWeightedStatsAvaliable = false;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -553,15 +553,15 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
if (widget.record.ownId != widget.record.replayId) Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
const Text("Number of rounds"),
|
||||
Text(t.numberOfRounds),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: widget.record.endContext.first.secondaryTracking.length > 0 ? widget.record.endContext.first.secondaryTracking.length.toString() : "---",
|
||||
text: widget.record.endContext.first.secondaryTracking.isNotEmpty ? widget.record.endContext.first.secondaryTracking.length.toString() : "---",
|
||||
style: TextStyle(
|
||||
fontFamily: "Eurostile Round Extended",
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: widget.record.endContext.first.secondaryTracking.length == 0 ? Colors.grey : null
|
||||
color: widget.record.endContext.first.secondaryTracking.isEmpty ? Colors.grey : Colors.white
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -570,18 +570,16 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
OverflowBar(
|
||||
alignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
TextButton( child: const Text('Match stats'),
|
||||
style: roundSelector == -1 ? ButtonStyle(backgroundColor: MaterialStatePropertyAll(Colors.grey.shade900)) : null,
|
||||
TextButton( style: roundSelector == -1 ? ButtonStyle(backgroundColor: MaterialStatePropertyAll(Colors.grey.shade900)) : null,
|
||||
onPressed: () {
|
||||
roundSelector = -1;
|
||||
setState(() {});
|
||||
}),
|
||||
TextButton( child: const Text('Time-weighted match stats'),
|
||||
style: roundSelector == -2 ? ButtonStyle(backgroundColor: MaterialStatePropertyAll(Colors.grey.shade900)) : null,
|
||||
}, child: Text(t.matchStats)),
|
||||
TextButton( style: roundSelector == -2 ? ButtonStyle(backgroundColor: MaterialStatePropertyAll(Colors.grey.shade900)) : null,
|
||||
onPressed: timeWeightedStatsAvaliable ? () {
|
||||
roundSelector = -2;
|
||||
setState(() {});
|
||||
} : null) ,
|
||||
} : null, child: Text(t.timeWeightedmatchStats)) ,
|
||||
//TextButton( child: const Text('Button 3'), onPressed: () {}),
|
||||
],
|
||||
)
|
||||
|
@ -624,7 +622,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
leading:RichText(
|
||||
text: TextSpan(
|
||||
text: "${time.inMinutes}:${NumberFormat("00", LocaleSettings.currentLocale.languageCode).format(time.inSeconds%60)}",
|
||||
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 22, fontWeight: FontWeight.w500),
|
||||
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 22, fontWeight: FontWeight.w500, color: Colors.white),
|
||||
children: [TextSpan(text: ".${NumberFormat("000", LocaleSettings.currentLocale.languageCode).format(time.inMilliseconds%1000)}", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))]
|
||||
),
|
||||
),
|
||||
|
@ -682,7 +680,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
}
|
||||
|
||||
Widget getMainWidget(double viewportWidth) {
|
||||
if (viewportWidth <= 1024) {
|
||||
if (viewportWidth <= 1200) {
|
||||
return Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 768),
|
||||
|
@ -692,9 +690,8 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
} else {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
//mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
SizedBox(
|
||||
width: 768,
|
||||
child: buildComparison(true, false)
|
||||
),
|
||||
|
@ -729,28 +726,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
onSelected: (value) async {
|
||||
switch (value) {
|
||||
case 1:
|
||||
if (kIsWeb){
|
||||
// final _base64 = base64Encode([1,2,3,4,5]);
|
||||
// final anchor = AnchorElement(href: 'data:application/octet-stream;base64,$_base64')..target = 'blank';
|
||||
//final anchor = AnchorElement(href: 'https://inoue.szy.lol/api/replay/${widget.record.replayId}')..target = 'blank';
|
||||
//anchor.download = "${widget.record.replayId}.ttrm";
|
||||
//document.body!.append(anchor);
|
||||
//anchor.click();
|
||||
//anchor.remove();
|
||||
} else{
|
||||
try{
|
||||
String path = await teto.saveReplay(widget.record.replayId);
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.replaySaved(path: path))));
|
||||
} on TetrioReplayAlreadyExist{
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.replayAlreadySaved)));
|
||||
} on SzyNotFound {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.replayExpired)));
|
||||
} on SzyForbidden {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.replayRejected)));
|
||||
} on SzyTooManyRequests {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.tooManyRequests)));
|
||||
}
|
||||
}
|
||||
await launchInBrowser(Uri.parse("https://inoue.szy.lol/api/replay/${widget.record.replayId}"));
|
||||
break;
|
||||
case 2:
|
||||
await launchInBrowser(Uri.parse("https://tetr.io/#r:${widget.record.replayId}"));
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/utils/colors_functions.dart';
|
||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
import 'package:tetra_stats/widgets/tl_thingy.dart';
|
||||
|
||||
|
@ -98,7 +99,7 @@ class GaugetNum extends StatelessWidget {
|
|||
oldPlayerStat! < playerStat ? Colors.redAccent : Colors.greenAccent
|
||||
),),
|
||||
if ((oldTl != null && oldTl!.gamesPlayed > 0) && pos != null) const TextSpan(text: " • "),
|
||||
if (pos != null) TextSpan(text: pos!.position >= 1000 ? "${t.top} ${f2.format(pos!.percentage*100)}%" : "№${pos!.position}")
|
||||
if (pos != null) TextSpan(text: pos!.position >= 1000 ? "${t.top} ${f2.format(pos!.percentage*100)}%" : "№${pos!.position}", style: TextStyle(color: getColorOfRank(pos!.position)))
|
||||
]
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
|
||||
final NumberFormat _f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
|
||||
class Graphs extends StatelessWidget{
|
||||
const Graphs(
|
||||
|
@ -125,13 +122,13 @@ class Graphs extends StatelessWidget{
|
|||
getTitle: (index, angle) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return RadarChartTitle(text: 'Opener\n${_f2.format(playstyle.opener)}', angle: 0, positionPercentageOffset: 0.05);
|
||||
return RadarChartTitle(text: 'Opener\n${percentage.format(playstyle.opener)}', angle: 0, positionPercentageOffset: 0.05);
|
||||
case 1:
|
||||
return RadarChartTitle(text: 'Stride\n${_f2.format(playstyle.stride)}', angle: 0, positionPercentageOffset: 0.05);
|
||||
return RadarChartTitle(text: 'Stride\n${percentage.format(playstyle.stride)}', angle: 0, positionPercentageOffset: 0.05);
|
||||
case 2:
|
||||
return RadarChartTitle(text: 'Inf Ds\n${_f2.format(playstyle.infds)}', angle: angle + 180, positionPercentageOffset: 0.05);
|
||||
return RadarChartTitle(text: 'Inf Ds\n${percentage.format(playstyle.infds)}', angle: angle + 180, positionPercentageOffset: 0.05);
|
||||
case 3:
|
||||
return RadarChartTitle(text: 'Plonk\n${_f2.format(playstyle.plonk)}', angle: 0, positionPercentageOffset: 0.05);
|
||||
return RadarChartTitle(text: 'Plonk\n${percentage.format(playstyle.plonk)}', angle: 0, positionPercentageOffset: 0.05);
|
||||
default:
|
||||
return const RadarChartTitle(text: '');
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class LineclearsThingy extends StatelessWidget{
|
|||
return Wrap(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Container(
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -30,7 +30,7 @@ class LineclearsThingy extends StatelessWidget{
|
|||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/utils/colors_functions.dart';
|
||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
|
||||
class StatCellNum extends StatelessWidget {
|
||||
|
@ -70,7 +71,7 @@ class StatCellNum extends StatelessWidget {
|
|||
oldPlayerStat! < playerStat ? Colors.redAccent : Colors.greenAccent
|
||||
),),
|
||||
if (oldPlayerStat != null && pos != null) const TextSpan(text: " • "),
|
||||
if (pos != null) TextSpan(text: pos!.position >= 1000 ? "${t.top} ${f2.format(pos!.percentage*100)}%" : "№${pos!.position}")
|
||||
if (pos != null) TextSpan(text: pos!.position >= 1000 ? "${t.top} ${f2.format(pos!.percentage*100)}%" : "№${pos!.position}", style: TextStyle(color: getColorOfRank(pos!.position)))
|
||||
]
|
||||
),
|
||||
),
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:tetra_stats/data_objects/tetrio.dart';
|
|||
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/main.dart';
|
||||
import 'package:tetra_stats/utils/colors_functions.dart';
|
||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
import 'package:tetra_stats/widgets/gauget_num.dart';
|
||||
import 'package:tetra_stats/widgets/graphs.dart';
|
||||
|
@ -299,7 +300,7 @@ class _TLThingyState extends State<TLThingy> {
|
|||
//alignment: Alignment.center,
|
||||
width: bigScreen ? MediaQuery.of(context).size.width * 0.4 : MediaQuery.of(context).size.width * 0.85,
|
||||
height: 70,
|
||||
constraints: BoxConstraints(maxWidth: 768),
|
||||
constraints: const BoxConstraints(maxWidth: 768),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
|
@ -307,12 +308,12 @@ class _TLThingyState extends State<TLThingy> {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(t.statCellNum.estOfTR, style: TextStyle(height: 0.1),),
|
||||
Text(t.statCellNum.estOfTR, style: const TextStyle(height: 0.1),),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: intf.format(currentTl.estTr!.esttr.truncate()),
|
||||
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 36 : 30, fontWeight: FontWeight.w500, color: Colors.white),
|
||||
children: [TextSpan(text: fractionfEstTR.format(currentTl.estTr!.esttr - currentTl.estTr!.esttr.truncate()).substring(1), style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))]
|
||||
children: [TextSpan(text: fractionfEstTR.format(currentTl.estTr!.esttr - currentTl.estTr!.esttr.truncate()).substring(1), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))]
|
||||
),
|
||||
),
|
||||
RichText(text: TextSpan(
|
||||
|
@ -323,7 +324,7 @@ 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 ? "${t.top} ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "№${widget.lbPositions!.estTr!.position}"),
|
||||
if (widget.lbPositions?.estTr != null) TextSpan(text: widget.lbPositions!.estTr!.position >= 1000 ? "${t.top} ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "№${widget.lbPositions!.estTr!.position}", style: TextStyle(color: getColorOfRank(widget.lbPositions!.estTr!.position))),
|
||||
if (widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
||||
TextSpan(text: "Glicko: ${f2.format(currentTl.estTr!.estglicko)}")
|
||||
]
|
||||
|
@ -342,7 +343,7 @@ class _TLThingyState extends State<TLThingy> {
|
|||
text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? intFDiff.format(currentTl.esttracc!.truncate()) : "---",
|
||||
style: TextStyle(fontFamily: "Eurostile Round", fontSize: bigScreen ? 36 : 30, fontWeight: FontWeight.w500, color: Colors.white),
|
||||
children: [
|
||||
TextSpan(text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? fractionfEstTRAcc.format(currentTl.esttracc!.isNegative ? 1 - (currentTl.esttracc! - currentTl.esttracc!.truncate()) : (currentTl.esttracc! - currentTl.esttracc!.truncate())).substring(1) : ".---", style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))
|
||||
TextSpan(text: (currentTl.esttracc != null && currentTl.bestRank != "z") ? fractionfEstTRAcc.format(currentTl.esttracc!.isNegative ? 1 - (currentTl.esttracc! - currentTl.esttracc!.truncate()) : (currentTl.esttracc! - currentTl.esttracc!.truncate())).substring(1) : ".---", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w100))
|
||||
]
|
||||
),
|
||||
),
|
||||
|
@ -354,7 +355,7 @@ class _TLThingyState extends State<TLThingy> {
|
|||
color: oldTl!.esttracc! > currentTl.esttracc! ? Colors.redAccent : Colors.greenAccent
|
||||
),),
|
||||
if (oldTl?.esttracc != null && widget.lbPositions?.accOfEst != null) const TextSpan(text: " • "),
|
||||
if (widget.lbPositions?.accOfEst != null) TextSpan(text: widget.lbPositions!.accOfEst!.position >= 1000 ? "${t.top} ${f2.format(widget.lbPositions!.accOfEst!.percentage*100)}%" : "№${widget.lbPositions!.accOfEst!.position}")
|
||||
if (widget.lbPositions?.accOfEst != null) TextSpan(text: widget.lbPositions!.accOfEst!.position >= 1000 ? "${t.top} ${f2.format(widget.lbPositions!.accOfEst!.percentage*100)}%" : "№${widget.lbPositions!.accOfEst!.position}", style: TextStyle(color: getColorOfRank(widget.lbPositions!.accOfEst!.position)))
|
||||
]
|
||||
),
|
||||
),
|
||||
|
|
|
@ -339,7 +339,7 @@ class UserThingy extends StatelessWidget {
|
|||
children: [
|
||||
if (player.country != null) TextSpan(text: "${t.countries[player.country]} • "),
|
||||
TextSpan(text: "${t.playerRole[player.role]}${t.playerRoleAccount}${player.registrationTime == null ? t.wasFromBeginning : '${t.created} ${dateFormat.format(player.registrationTime!)}'}"),
|
||||
if (player.supporterTier > 0) TextSpan(text: " • "),
|
||||
if (player.supporterTier > 0) const TextSpan(text: " • "),
|
||||
if (player.supporterTier > 0) WidgetSpan(child: Icon(player.supporterTier > 1 ? Icons.star : Icons.star_border, color: player.supporterTier > 1 ? Colors.yellowAccent : Colors.white), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic),
|
||||
if (player.supporterTier > 0) TextSpan(text: player.supporterTier.toString(), style: TextStyle(color: player.supporterTier > 1 ? Colors.yellowAccent : Colors.white))
|
||||
]
|
||||
|
|
244
pubspec.lock
|
@ -5,26 +5,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
|
||||
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "64.0.0"
|
||||
version: "67.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
|
||||
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "6.4.1"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b"
|
||||
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.9"
|
||||
version: "3.4.10"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -141,10 +141,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: dev_build
|
||||
sha256: e476ac99174842cdb01e64c1d379d041d2150f9ad2cdd2713eb1ca1bdbf30507
|
||||
sha256: e5d575f3de4b0e5f004e065e1e2d98fa012d634b61b5855216b5698ed7f1e443
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.16.3+2"
|
||||
version: "0.16.4+3"
|
||||
equatable:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -165,10 +165,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -181,34 +181,34 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
|
||||
sha256: "1bbf65dd997458a08b531042ec3794112a6c39c07c37ff22113d2e7e4f81d4e4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.1"
|
||||
version: "6.2.1"
|
||||
file_selector:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_selector
|
||||
sha256: "84eaf3e034d647859167d1f01cfe7b6352488f34c1b4932635012b202014c25b"
|
||||
sha256: "5019692b593455127794d5718304ff1ae15447dea286cdda9f0db2a796a1b828"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.3"
|
||||
file_selector_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_android
|
||||
sha256: b7556052dbcc25ef88f6eba45ab98aa5600382af8dfdabc9d644a93d97b7be7f
|
||||
sha256: "1cd66575f063b689e041aec836905ba7be18d76c9f0634d0d75daec825f67095"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0+4"
|
||||
version: "0.5.0+7"
|
||||
file_selector_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_ios
|
||||
sha256: "2f48db7e338b2255101c35c604b7ca5ab588dce032db7fc418a2fe5f28da63f8"
|
||||
sha256: b015154e6d9fddbc4d08916794df170b44531798c8dd709a026df162d07ad81d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1+7"
|
||||
version: "0.5.1+8"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -229,10 +229,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262"
|
||||
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.1"
|
||||
version: "2.6.2"
|
||||
file_selector_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -253,10 +253,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: fl_chart
|
||||
sha256: fe6fec7d85975a99c73b9515a69a6e291364accfa0e4a5b3ce6de814d74b9a1c
|
||||
sha256: "00b74ae680df6b1135bdbea00a7d1fc072a9180b7c3f3702e4b19a9943f5ed7d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.66.0"
|
||||
version: "0.66.2"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -295,10 +295,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_markdown
|
||||
sha256: "35108526a233cc0755664d445f8a6b4b61e6f8fe993b3658b80b4a26827fc196"
|
||||
sha256: "87e11b9df25a42e2db315b8b7a51fae8e66f57a4b2f50ec4b822d0fa155e6b52"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.18+2"
|
||||
version: "0.6.22"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -311,10 +311,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
|
||||
sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
version: "2.0.10+1"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -345,18 +345,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: ca7e4a2249f96773152f1853fa25933ac752495cdd7fdf5dafb9691bd05830fd
|
||||
sha256: "7ecb2f391edbca5473db591b48555a8912dde60edd0fb3013bd6743033b2d3f8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
version: "13.2.1"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
|
||||
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.2.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -377,10 +377,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271"
|
||||
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.3"
|
||||
version: "4.1.7"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -421,6 +421,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.1"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.0"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -441,34 +465,34 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: markdown
|
||||
sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd
|
||||
sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.1.1"
|
||||
version: "7.2.2"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16"
|
||||
version: "0.12.16+1"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.8.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -513,10 +537,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
version: "1.9.0"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -529,26 +553,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
|
||||
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.2"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
|
||||
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.2.2"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
|
||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.2"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -561,10 +585,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
|
||||
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.2"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -585,26 +609,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "3.1.4"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
|
||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.7"
|
||||
version: "2.1.8"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
|
||||
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.7.3"
|
||||
version: "3.7.4"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -617,10 +641,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: process_run
|
||||
sha256: "3d5335d17003a7c2fd5148be2d313f5b84244ab2e625162fdd44b4aaa48bea66"
|
||||
sha256: "8d9c6198b98fbbfb511edd42e7364e24d85c163e47398919871b952dc86a423e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.3+1"
|
||||
version: "0.14.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -657,10 +681,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
|
||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.4"
|
||||
version: "2.3.5"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -673,10 +697,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
|
||||
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.2"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -734,18 +758,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: slang
|
||||
sha256: "77fd99f7b0da15e671ef0289b24a0a63e74f693c58a0ca54111388e4c0ddb1dd"
|
||||
sha256: "5e08ac915ac27a3508863f37734280d30c3713d56746cd2e4a5da77413da4b95"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.28.0"
|
||||
version: "3.30.1"
|
||||
slang_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: slang_flutter
|
||||
sha256: "57817bb15553bb5df37aed3bac497286bdd8c2eab6763f4de6815efe2c0becee"
|
||||
sha256: "9ee040b0d364d3a4d692e4af536acff6ef513870689403494ebc6d59b0dccea6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.28.0"
|
||||
version: "3.30.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -774,50 +798,50 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
|
||||
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.3.2"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6
|
||||
sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.0+2"
|
||||
version: "2.5.4"
|
||||
sqflite_common_ffi:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqflite_common_ffi
|
||||
sha256: "873677ee78738a723d1ded4ccb23980581998d873d30ee9c331f6a81748663ff"
|
||||
sha256: "4d6137c29e930d6e4a8ff373989dd9de7bac12e3bc87bce950f6e844e8ad3bb5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.3"
|
||||
sqflite_common_ffi_web:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqflite_common_ffi_web
|
||||
sha256: "3d4b550a09fda9eb0a9ce3bd98c8080f57b2cc1f4b19e844290e82843e73b63d"
|
||||
sha256: "0c2921454d2e4a227675fb952be9fef916cf65fb9e9b606b54cfdf080d3e9450"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.2+2"
|
||||
version: "0.4.2+3"
|
||||
sqlite3:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqlite3
|
||||
sha256: c4a4c5a4b2a32e2d0f6837b33d7c91a67903891a5b7dbe706cf4b1f6b0c798c5
|
||||
sha256: "072128763f1547e3e9b4735ce846bfd226d68019ccda54db4cd427b12dfdedc9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.4.0"
|
||||
sqlite3_flutter_libs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3_flutter_libs
|
||||
sha256: "3e3583b77cf888a68eae2e49ee4f025f66b86623ef0d83c297c8d903daa14871"
|
||||
sha256: d6c31c8511c441d1f12f20b607343df1afe4eddf24a1cf85021677c8eea26060
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.18"
|
||||
version: "0.5.20"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -846,18 +870,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: "69c827931957d5b121ee9f0b9b0b8d7d0d1ac537b61bcdd5c3fbffc044bbe86e"
|
||||
sha256: "7666506885ebc8f62bb928ad4588a73e20caaff2b2cf2b2b56f67d98f4113525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "24.1.41"
|
||||
version: "24.2.9"
|
||||
syncfusion_flutter_gauges:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_gauges
|
||||
sha256: "78515dcfbed952c36ab9ca4a1e6c99737beb7c6cf2312efe8beca2bd314a3955"
|
||||
sha256: "87be13e520fc1676a725691446f411f549ea5b6ff2580234db0479799f213757"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "24.1.41"
|
||||
version: "24.2.9"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -910,26 +934,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86
|
||||
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.2"
|
||||
version: "6.2.5"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def"
|
||||
sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "6.3.0"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3
|
||||
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.1"
|
||||
version: "6.2.5"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -950,18 +974,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50"
|
||||
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.3.2"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9"
|
||||
sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "2.2.3"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -974,26 +998,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics
|
||||
sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43"
|
||||
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.9+1"
|
||||
version: "1.1.11+1"
|
||||
vector_graphics_codec:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_codec
|
||||
sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7"
|
||||
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.9+1"
|
||||
version: "1.1.11+1"
|
||||
vector_graphics_compiler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_compiler
|
||||
sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26
|
||||
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.9+1"
|
||||
version: "1.1.11+1"
|
||||
vector_math:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1022,18 +1046,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||
sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.4.2"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
||||
sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1046,26 +1070,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
|
||||
sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
version: "5.3.0"
|
||||
window_manager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: window_manager
|
||||
sha256: dcc865277f26a7dad263a47d0e405d77e21f12cb71f30333a52710a408690bd7
|
||||
sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.7"
|
||||
version: "0.3.8"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
|
||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.4"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1083,5 +1107,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.2.0 <4.0.0"
|
||||
flutter: ">=3.16.0"
|
||||
dart: ">=3.3.0 <4.0.0"
|
||||
flutter: ">=3.19.0"
|
||||
|
|
|
@ -2,7 +2,7 @@ name: tetra_stats
|
|||
description: Track your and other player stats in TETR.IO
|
||||
publish_to: 'none'
|
||||
|
||||
version: 1.4.1+15
|
||||
version: 1.5.0+16
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.0'
|
||||
|
|
|
@ -48,11 +48,11 @@
|
|||
"noRecords": "No records",
|
||||
"noOldRecords": {
|
||||
"zero": "No records",
|
||||
"one": "$n record",
|
||||
"two": "$n records",
|
||||
"few": "$n records",
|
||||
"many": "$n records",
|
||||
"other": "$n records"
|
||||
"one": "Only $n record",
|
||||
"two": "Only $n records",
|
||||
"few": "Only $n records",
|
||||
"many": "Only $n records",
|
||||
"other": "Only $n records"
|
||||
},
|
||||
"noRecord": "No record",
|
||||
"botRecord": "Bots are not allowed to set records",
|
||||
|
@ -77,7 +77,7 @@
|
|||
"supporter": "Supporter tier ${tier}",
|
||||
"comparingWith": "Data from ${newDate} comparing with ${oldDate}",
|
||||
"top": "Top",
|
||||
"topRank": "Top Rank",
|
||||
"topRank": "Top rank",
|
||||
"verdictGeneral": "$n $verdict than $rank rank average",
|
||||
"verdictBetter": "better",
|
||||
"verdictWorse": "worse",
|
||||
|
@ -136,10 +136,14 @@
|
|||
"openReplay": "Open replay in TETR.IO",
|
||||
"replaySaved": "Replay saved to ${path}",
|
||||
"match": "Match",
|
||||
"timeWeightedmatch": "Match (time-weighted)",
|
||||
"roundNumber": "Round $n",
|
||||
"statsFor": "Stats for",
|
||||
"numberOfRounds": "Number of rounds",
|
||||
"matchLength": "Match Length",
|
||||
"roundLength": "Round Length",
|
||||
"matchStats": "Match stats",
|
||||
"timeWeightedmatchStats": "Time-weighted match stats",
|
||||
"replayIssue": "Can't process replay",
|
||||
"matchIsTooOld": "Replay is not available",
|
||||
"winner": "Winner",
|
||||
|
@ -176,6 +180,15 @@
|
|||
"many": "$n players",
|
||||
"other": "$n players"
|
||||
},
|
||||
"games": {
|
||||
"zero": "$n games",
|
||||
"one": "$n game",
|
||||
"two": "$n games",
|
||||
"few": "$n games",
|
||||
"many": "$n games",
|
||||
"other": "$n games"
|
||||
},
|
||||
"gamesPlayed": "$games played",
|
||||
"chart": "Chart",
|
||||
"entries": "Entries",
|
||||
"minimums": "Minimums",
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
"assignedManualy": "Этот значок был присвоен вручную администрацией TETR.IO",
|
||||
"comparingWith": "Данные от ${newDate} в сравнении с данными от ${oldDate}",
|
||||
"top": "Топ",
|
||||
"topRank": "Топ Ранг",
|
||||
"topRank": "Топ ранг",
|
||||
"verdictGeneral": "$verdict среднего $rank ранга на $n",
|
||||
"verdictBetter": "Лучше",
|
||||
"verdictWorse": "Хуже",
|
||||
|
@ -136,10 +136,14 @@
|
|||
"openReplay": "Открыть повтор в TETR.IO",
|
||||
"replaySaved": "Повтор сохранён по пути ${path}",
|
||||
"match": "Матч",
|
||||
"timeWeightedmatch": "Матч (взвешенная по времени)",
|
||||
"roundNumber": "Раунд $n",
|
||||
"statsFor": "Статистика за",
|
||||
"numberOfRounds": "Количество раундов",
|
||||
"matchLength": "Продолжительность матча",
|
||||
"roundLength": "Продолжительность раунда",
|
||||
"matchStats": "Статистика матча",
|
||||
"timeWeightedmatchStats": "Взвешенная по времени cтатистика матча",
|
||||
"replayIssue": "Ошибка обработки повтора",
|
||||
"matchIsTooOld": "Информация о повторе недоступна",
|
||||
"winner": "Победитель",
|
||||
|
@ -176,6 +180,15 @@
|
|||
"many": "$n игроков",
|
||||
"other": "$n игроков"
|
||||
},
|
||||
"games": {
|
||||
"zero": "$n игр",
|
||||
"one": "$n игра",
|
||||
"two": "$n игры",
|
||||
"few": "$n игры",
|
||||
"many": "$n игр",
|
||||
"other": "$n игр"
|
||||
},
|
||||
"gamesPlayed": "$games сыграно",
|
||||
"chart": "График",
|
||||
"entries": "Список",
|
||||
"minimums": "Минимумы",
|
||||
|
|
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 28 KiB |