Really wacky implementation of interactivity for history graph + very small things
This commit is contained in:
parent
e524952970
commit
a6b3a0282a
|
@ -940,9 +940,9 @@ class TetraLeagueAlpha {
|
||||||
rd = json['rd'] != null ? json['rd']!.toDouble() : noTrRd;
|
rd = json['rd'] != null ? json['rd']!.toDouble() : noTrRd;
|
||||||
rank = json['rank'] != null ? json['rank']!.toString() : 'z';
|
rank = json['rank'] != null ? json['rank']!.toString() : 'z';
|
||||||
bestRank = json['bestrank'] != null ? json['bestrank']!.toString() : 'z';
|
bestRank = json['bestrank'] != null ? json['bestrank']!.toString() : 'z';
|
||||||
apm = json['apm'] != null ? json['apm']!.toDouble() : null;
|
apm = json['apm']?.toDouble();
|
||||||
pps = json['pps'] != null ? json['pps']!.toDouble() : null;
|
pps = json['pps']?.toDouble();
|
||||||
vs = json['vs'] != null ? json['vs']!.toDouble() : null;
|
vs = json['vs']?.toDouble();
|
||||||
decaying = json['decaying'] ?? false;
|
decaying = json['decaying'] ?? false;
|
||||||
standing = json['standing'] ?? -1;
|
standing = json['standing'] ?? -1;
|
||||||
percentile = json['percentile'] != null ? json['percentile'].toDouble() : rankCutoffs[rank];
|
percentile = json['percentile'] != null ? json['percentile'].toDouble() : rankCutoffs[rank];
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'tetrio.dart';
|
import 'tetrio.dart';
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
late final PackageInfo packageInfo;
|
late final PackageInfo packageInfo;
|
||||||
late SharedPreferences prefs;
|
late SharedPreferences prefs;
|
||||||
ColorScheme sheme = ColorScheme.dark(primary: Colors.cyanAccent, secondary: Colors.white);
|
ColorScheme sheme = const ColorScheme.dark(primary: Colors.cyanAccent, secondary: Colors.white);
|
||||||
|
|
||||||
void setAccentColor(Color color){
|
void setAccentColor(Color color){
|
||||||
sheme = ColorScheme.dark(primary: color, secondary: Colors.white);
|
sheme = ColorScheme.dark(primary: color, secondary: Colors.white);
|
||||||
|
|
|
@ -17,7 +17,7 @@ final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings
|
||||||
late String oldWindowTitle;
|
late String oldWindowTitle;
|
||||||
|
|
||||||
class CalcView extends StatefulWidget {
|
class CalcView extends StatefulWidget {
|
||||||
const CalcView({Key? key}) : super(key: key);
|
const CalcView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => CalcState();
|
State<StatefulWidget> createState() => CalcState();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -28,8 +30,7 @@ class CompareView extends StatefulWidget {
|
||||||
final List<dynamic> redSide;
|
final List<dynamic> redSide;
|
||||||
final Mode greenMode;
|
final Mode greenMode;
|
||||||
final Mode redMode;
|
final Mode redMode;
|
||||||
const CompareView({Key? key, required this.greenSide, required this.redSide, required this.greenMode, required this.redMode})
|
const CompareView({super.key, required this.greenSide, required this.redSide, required this.greenMode, required this.redMode});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => CompareState();
|
State<StatefulWidget> createState() => CompareState();
|
||||||
|
|
|
@ -12,7 +12,7 @@ Color pickerColor = Colors.cyanAccent;
|
||||||
Color currentColor = Colors.cyanAccent;
|
Color currentColor = Colors.cyanAccent;
|
||||||
|
|
||||||
class CustomizationView extends StatefulWidget {
|
class CustomizationView extends StatefulWidget {
|
||||||
const CustomizationView({Key? key}) : super(key: key);
|
const CustomizationView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => CustomizationState();
|
State<StatefulWidget> createState() => CustomizationState();
|
||||||
|
@ -67,7 +67,7 @@ class CustomizationState extends State<CustomizationView> {
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text("Accent Color"),
|
title: const Text("Accent Color"),
|
||||||
trailing: ColorIndicator(HSVColor.fromColor(Theme.of(context).colorScheme.primary)),
|
trailing: ColorIndicator(HSVColor.fromColor(Theme.of(context).colorScheme.primary)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
@ -111,11 +111,11 @@ class CustomizationState extends State<CustomizationView> {
|
||||||
),
|
),
|
||||||
]));
|
]));
|
||||||
}),
|
}),
|
||||||
ListTile(
|
const ListTile(
|
||||||
title: Text("Font"),
|
title: Text("Font"),
|
||||||
subtitle: Text("Not implemented"),
|
subtitle: Text("Not implemented"),
|
||||||
),
|
),
|
||||||
ListTile(
|
const ListTile(
|
||||||
title: Text("Stats Table in TL mathes list"),
|
title: Text("Stats Table in TL mathes list"),
|
||||||
subtitle: Text("Not implemented"),
|
subtitle: Text("Not implemented"),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// ignore_for_file: type_literal_in_constant_pattern
|
// ignore_for_file: type_literal_in_constant_pattern
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
@ -12,7 +12,6 @@ import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetrio_multiplayer_replay.dart';
|
|
||||||
import 'package:tetra_stats/gen/strings.g.dart';
|
import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
import 'package:tetra_stats/services/tetrio_crud.dart';
|
import 'package:tetra_stats/services/tetrio_crud.dart';
|
||||||
import 'package:tetra_stats/main.dart' show prefs;
|
import 'package:tetra_stats/main.dart' show prefs;
|
||||||
|
@ -34,6 +33,7 @@ final TetrioService teto = TetrioService();
|
||||||
var chartsData = <DropdownMenuItem<List<FlSpot>>>[];
|
var chartsData = <DropdownMenuItem<List<FlSpot>>>[];
|
||||||
List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR"];
|
List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR"];
|
||||||
int _chartsIndex = 0;
|
int _chartsIndex = 0;
|
||||||
|
late ScrollController _scrollController;
|
||||||
final NumberFormat _timeInSec = NumberFormat("#,###.###s.");
|
final NumberFormat _timeInSec = NumberFormat("#,###.###s.");
|
||||||
final NumberFormat secs = NumberFormat("00.###");
|
final NumberFormat secs = NumberFormat("00.###");
|
||||||
final NumberFormat _f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
final NumberFormat _f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
||||||
|
@ -42,7 +42,7 @@ final DateFormat _dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.lan
|
||||||
|
|
||||||
class MainView extends StatefulWidget {
|
class MainView extends StatefulWidget {
|
||||||
final String? player;
|
final String? player;
|
||||||
const MainView({Key? key, this.player}) : super(key: key);
|
const MainView({super.key, this.player});
|
||||||
|
|
||||||
String get title => "Tetra Stats: $_titleNickname";
|
String get title => "Tetra Stats: $_titleNickname";
|
||||||
|
|
||||||
|
@ -58,11 +58,10 @@ String get40lTime(int microseconds){
|
||||||
return microseconds > 60000000 ? "${(microseconds/1000000/60).floor()}:${(secs.format(microseconds /1000000 % 60))}" : _timeInSec.format(microseconds / 1000000);
|
return microseconds > 60000000 ? "${(microseconds/1000000/60).floor()}:${(secs.format(microseconds /1000000 % 60))}" : _timeInSec.format(microseconds / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
final bodyGlobalKey = GlobalKey();
|
final bodyGlobalKey = GlobalKey();
|
||||||
bool _searchBoolean = false;
|
bool _searchBoolean = false;
|
||||||
late TabController _tabController;
|
late TabController _tabController;
|
||||||
late ScrollController _scrollController;
|
|
||||||
late bool fixedScroll;
|
late bool fixedScroll;
|
||||||
|
|
||||||
Widget _searchTextField() {
|
Widget _searchTextField() {
|
||||||
|
@ -313,13 +312,13 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
onRefresh: () {
|
onRefresh: () {
|
||||||
return Future(() => changePlayer(snapshot.data![0].userId));
|
return Future(() => changePlayer(snapshot.data![0].userId));
|
||||||
},
|
},
|
||||||
// notificationPredicate: (notification) {
|
notificationPredicate: (notification) {
|
||||||
// // with NestedScrollView local(depth == 2) OverscrollNotification are not sent
|
// with NestedScrollView local(depth == 2) OverscrollNotification are not sent
|
||||||
// if (!kIsWeb && (notification is OverscrollNotification || Platform.isIOS)) {
|
if (!kIsWeb && (notification is OverscrollNotification || Platform.isIOS)) {
|
||||||
// return notification.depth == 2;
|
return notification.depth == 2;
|
||||||
// }
|
}
|
||||||
// return notification.depth == 0;
|
return notification.depth == 0;
|
||||||
// },
|
},
|
||||||
child: NestedScrollView(
|
child: NestedScrollView(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
@ -334,7 +333,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: TabBar(
|
child: TabBar(
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
padding: EdgeInsets.all(0.0),
|
padding: const EdgeInsets.all(0.0),
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(text: t.tetraLeague),
|
Tab(text: t.tetraLeague),
|
||||||
|
@ -423,18 +422,15 @@ class NavDrawer extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NavDrawerState extends State<NavDrawer> {
|
class _NavDrawerState extends State<NavDrawer> {
|
||||||
late ScrollController _scrollController;
|
|
||||||
String homePlayerNickname = "Checking...";
|
String homePlayerNickname = "Checking...";
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_setHomePlayerNickname(prefs.getString("player"));
|
_setHomePlayerNickname(prefs.getString("player"));
|
||||||
_scrollController = ScrollController();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_scrollController.dispose();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,8 +580,7 @@ class _History extends StatelessWidget{
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
||||||
return ListView(physics: const ClampingScrollPhysics(),
|
return states.isNotEmpty ?
|
||||||
children: states.isNotEmpty ? [
|
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
DropdownButton(
|
DropdownButton(
|
||||||
|
@ -599,34 +594,114 @@ class _History extends StatelessWidget{
|
||||||
if(chartsData[_chartsIndex].value!.length > 1) _HistoryChartThigy(data: chartsData[_chartsIndex].value!, title: "ss", yAxisTitle: _historyShortTitles[_chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? _f2 : NumberFormat.compact(),)
|
if(chartsData[_chartsIndex].value!.length > 1) _HistoryChartThigy(data: chartsData[_chartsIndex].value!, title: "ss", yAxisTitle: _historyShortTitles[_chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? _f2 : NumberFormat.compact(),)
|
||||||
else Center(child: Text(t.notEnoughData, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)))
|
else Center(child: Text(t.notEnoughData, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)))
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
] : [Center(child: Text(t.noHistorySaved, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)))]);
|
: Center(child: Text(t.noHistorySaved, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HistoryChartThigy extends StatelessWidget{
|
class _HistoryChartThigy extends StatefulWidget{
|
||||||
final List<FlSpot> data;
|
final List<FlSpot> data;
|
||||||
final String title;
|
final String title;
|
||||||
final String yAxisTitle;
|
final String yAxisTitle;
|
||||||
final bool bigScreen;
|
final bool bigScreen;
|
||||||
final double leftSpace;
|
final double leftSpace;
|
||||||
final NumberFormat yFormat;
|
final NumberFormat yFormat;
|
||||||
|
|
||||||
const _HistoryChartThigy({required this.data, required this.title, required this.yAxisTitle, required this.bigScreen, required this.leftSpace, required this.yFormat});
|
const _HistoryChartThigy({required this.data, required this.title, required this.yAxisTitle, required this.bigScreen, required this.leftSpace, required this.yFormat});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_HistoryChartThigy> createState() => _HistoryChartThigyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
||||||
|
late double minX;
|
||||||
|
late double maxX;
|
||||||
|
late double minY;
|
||||||
|
late double maxY;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState(){
|
||||||
|
super.initState();
|
||||||
|
minX = widget.data.first.x;
|
||||||
|
maxX = widget.data.last.x;
|
||||||
|
minY = widget.data.reduce((value, element){
|
||||||
|
num n = min(value.y, element.y);
|
||||||
|
if (value.y == n) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}).y;
|
||||||
|
maxY = widget.data.reduce((value, element){
|
||||||
|
num n = max(value.y, element.y);
|
||||||
|
if (value.y == n) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}).y;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
double xInterval = bigScreen ? max(1, (data.last.x - data.first.x) / 6) : max(1, (data.last.x - data.first.x) / 3);
|
double xScale = maxX - minX;
|
||||||
|
double xInterval = widget.bigScreen ? max(1, xScale / 6) : max(1, xScale / 3);
|
||||||
|
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;
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height - 100,
|
height: MediaQuery.of(context).size.height - 104,
|
||||||
child: Stack(
|
child: Listener(
|
||||||
children: [
|
onPointerSignal: (signal) {
|
||||||
Padding( padding: bigScreen ? const EdgeInsets.fromLTRB(40, 40, 40, 48) : const EdgeInsets.fromLTRB(0, 40, 16, 48) ,
|
if (signal is PointerScrollEvent) {
|
||||||
|
double scrollPosRelativeX = (signal.position.dx - graphStartX) / (graphEndX - graphStartX);
|
||||||
|
double newMinX, newMaxX;
|
||||||
|
newMinX = minX - (xScale / 5e2) * signal.scrollDelta.dy * scrollPosRelativeX;
|
||||||
|
newMaxX = maxX + (xScale / 5e2) * signal.scrollDelta.dy * (1-scrollPosRelativeX);
|
||||||
|
if ((newMaxX - newMinX).isNegative) return;
|
||||||
|
setState(() {
|
||||||
|
minX = max(newMinX, widget.data.first.x);
|
||||||
|
maxX = min(newMaxX, widget.data.last.x);
|
||||||
|
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child:
|
||||||
|
GestureDetector(
|
||||||
|
onDoubleTap: () {
|
||||||
|
setState(() {
|
||||||
|
minX = widget.data.first.x;
|
||||||
|
maxX = widget.data.last.x;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onHorizontalDragUpdate: (dragUpdDet) {
|
||||||
|
var horizontalDistance = dragUpdDet.primaryDelta ?? 0;
|
||||||
|
if (horizontalDistance == 0) return;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
minX -= (xScale / 7e2) * horizontalDistance;
|
||||||
|
maxX -= (xScale / 7e2) * horizontalDistance;
|
||||||
|
|
||||||
|
if (minX < widget.data.first.x) {
|
||||||
|
minX = widget.data.first.x;
|
||||||
|
maxX = widget.data.first.x + xScale;
|
||||||
|
}
|
||||||
|
if (maxX > widget.data.last.x) {
|
||||||
|
maxX = widget.data.last.x;
|
||||||
|
minX = maxX - xScale;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Padding( padding: padding,
|
||||||
child: LineChart(
|
child: LineChart(
|
||||||
LineChartData(
|
LineChartData(
|
||||||
lineBarsData: [LineChartBarData(spots: data)],
|
lineBarsData: [LineChartBarData(spots: widget.data)],
|
||||||
|
clipData: const FlClipData.all(),
|
||||||
borderData: FlBorderData(show: false),
|
borderData: FlBorderData(show: false),
|
||||||
gridData: FlGridData(verticalInterval: xInterval),
|
gridData: FlGridData(verticalInterval: xInterval),
|
||||||
|
minX: minX,
|
||||||
|
maxX: maxX,
|
||||||
titlesData: FlTitlesData(topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
titlesData: FlTitlesData(topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||||
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||||
bottomTitles: AxisTitles(sideTitles: SideTitles(interval: xInterval, showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){
|
bottomTitles: AxisTitles(sideTitles: SideTitles(interval: xInterval, showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){
|
||||||
|
@ -635,19 +710,19 @@ class _HistoryChartThigy extends StatelessWidget{
|
||||||
child: Text(DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))),
|
child: Text(DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))),
|
||||||
) : Container();
|
) : Container();
|
||||||
})),
|
})),
|
||||||
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: leftSpace, getTitlesWidget: (double value, TitleMeta meta){
|
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: widget.leftSpace, getTitlesWidget: (double value, TitleMeta meta){
|
||||||
return value != meta.min && value != meta.max ? SideTitleWidget(
|
return value != meta.min && value != meta.max ? SideTitleWidget(
|
||||||
axisSide: meta.axisSide,
|
axisSide: meta.axisSide,
|
||||||
child: Text(yFormat.format(value)),
|
child: Text(widget.yFormat.format(value)),
|
||||||
) : Container();
|
) : Container();
|
||||||
}))),
|
}))),
|
||||||
lineTouchData: LineTouchData(touchTooltipData: LineTouchTooltipData( fitInsideHorizontally: true, fitInsideVertically: true, getTooltipItems: (touchedSpots) {
|
lineTouchData: LineTouchData(touchTooltipData: LineTouchTooltipData( fitInsideHorizontally: true, fitInsideVertically: true, getTooltipItems: (touchedSpots) {
|
||||||
return [for (var v in touchedSpots) LineTooltipItem("${_f4.format(v.y)} $yAxisTitle \n", const TextStyle(), children: [TextSpan(text: _dateFormat.format(DateTime.fromMillisecondsSinceEpoch(v.x.floor())))])];
|
return [for (var v in touchedSpots) LineTooltipItem("${_f4.format(v.y)} ${widget.yAxisTitle} \n", const TextStyle(), children: [TextSpan(text: _dateFormat.format(DateTime.fromMillisecondsSinceEpoch(v.x.floor())))])];
|
||||||
},))
|
},))
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -655,7 +730,7 @@ class _HistoryChartThigy extends StatelessWidget{
|
||||||
|
|
||||||
class _RecordThingy extends StatelessWidget {
|
class _RecordThingy extends StatelessWidget {
|
||||||
final RecordSingle? record;
|
final RecordSingle? record;
|
||||||
const _RecordThingy({Key? key, required this.record}) : super(key: key);
|
const _RecordThingy({required this.record});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -900,8 +975,7 @@ class _OtherThingy extends StatelessWidget {
|
||||||
final String? bio;
|
final String? bio;
|
||||||
final Distinguishment? distinguishment;
|
final Distinguishment? distinguishment;
|
||||||
final List<News>? newsletter;
|
final List<News>? newsletter;
|
||||||
const _OtherThingy({Key? key, required this.zen, required this.bio, required this.distinguishment, this.newsletter})
|
const _OtherThingy({required this.zen, required this.bio, required this.distinguishment, this.newsletter});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
List<InlineSpan> getDistinguishmentTitle(String? text) {
|
List<InlineSpan> getDistinguishmentTitle(String? text) {
|
||||||
if (distinguishment?.type == "twc") return [const TextSpan(text: "TETR.IO World Champion", style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.yellowAccent))];
|
if (distinguishment?.type == "twc") return [const TextSpan(text: "TETR.IO World Champion", style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.yellowAccent))];
|
||||||
|
|
|
@ -14,7 +14,7 @@ late String oldWindowTitle;
|
||||||
class MatchesView extends StatefulWidget {
|
class MatchesView extends StatefulWidget {
|
||||||
final String userID;
|
final String userID;
|
||||||
final String username;
|
final String username;
|
||||||
const MatchesView({Key? key, required this.userID, required this.username}) : super(key: key);
|
const MatchesView({super.key, required this.userID, required this.username});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => MatchesState();
|
State<StatefulWidget> createState() => MatchesState();
|
||||||
|
|
|
@ -22,7 +22,7 @@ final NumberFormat _f4 = NumberFormat.decimalPatternDigits(locale: LocaleSetting
|
||||||
|
|
||||||
class RankView extends StatefulWidget {
|
class RankView extends StatefulWidget {
|
||||||
final List rank;
|
final List rank;
|
||||||
const RankView({Key? key, required this.rank}) : super(key: key);
|
const RankView({super.key, required this.rank});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => RankState();
|
State<StatefulWidget> createState() => RankState();
|
||||||
|
@ -505,5 +505,5 @@ class _MyScatterSpot extends ScatterSpot {
|
||||||
String nickname;
|
String nickname;
|
||||||
//Color color;
|
//Color color;
|
||||||
//FlDotPainter painter = FlDotCirclePainter(color: color, radius: 2);
|
//FlDotPainter painter = FlDotCirclePainter(color: color, radius: 2);
|
||||||
_MyScatterSpot(super.x, super.y, this.id, this.nickname, {FlDotPainter? super.dotPainter});
|
_MyScatterSpot(super.x, super.y, this.id, this.nickname, {super.dotPainter});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:window_manager/window_manager.dart';
|
||||||
import 'main_view.dart'; // lol
|
import 'main_view.dart'; // lol
|
||||||
|
|
||||||
class RankAveragesView extends StatefulWidget {
|
class RankAveragesView extends StatefulWidget {
|
||||||
const RankAveragesView({Key? key}) : super(key: key);
|
const RankAveragesView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => RanksAverages();
|
State<StatefulWidget> createState() => RanksAverages();
|
||||||
|
|
|
@ -15,7 +15,7 @@ import 'package:window_manager/window_manager.dart';
|
||||||
late String oldWindowTitle;
|
late String oldWindowTitle;
|
||||||
|
|
||||||
class SettingsView extends StatefulWidget {
|
class SettingsView extends StatefulWidget {
|
||||||
const SettingsView({Key? key}) : super(key: key);
|
const SettingsView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => SettingsState();
|
State<StatefulWidget> createState() => SettingsState();
|
||||||
|
@ -236,9 +236,9 @@ class SettingsState extends State<SettingsView> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(title: Text("Customization"),
|
ListTile(title: const Text("Customization"),
|
||||||
subtitle: Text("I don't want to implement this"),
|
subtitle: const Text("I don't want to implement this"),
|
||||||
trailing: Icon(Icons.arrow_right),
|
trailing: const Icon(Icons.arrow_right),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(context, "/customization");
|
Navigator.pushNamed(context, "/customization");
|
||||||
},),
|
},),
|
||||||
|
|
|
@ -12,7 +12,7 @@ final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.lang
|
||||||
|
|
||||||
class StateView extends StatefulWidget {
|
class StateView extends StatefulWidget {
|
||||||
final TetrioPlayer state;
|
final TetrioPlayer state;
|
||||||
const StateView({Key? key, required this.state}) : super(key: key);
|
const StateView({super.key, required this.state});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => StateState();
|
State<StatefulWidget> createState() => StateState();
|
||||||
|
@ -58,6 +58,6 @@ class StateState extends State<StateView> {
|
||||||
headerSliverBuilder: (context, value) {
|
headerSliverBuilder: (context, value) {
|
||||||
return [SliverToBoxAdapter(child: UserThingy(player: widget.state, showStateTimestamp: true, setState: _justUpdate))];
|
return [SliverToBoxAdapter(child: UserThingy(player: widget.state, showStateTimestamp: true, setState: _justUpdate))];
|
||||||
},
|
},
|
||||||
body: TLThingy(tl: widget.state.tlSeason1, userID: widget.state.userId, states: [],))));
|
body: TLThingy(tl: widget.state.tlSeason1, userID: widget.state.userId, states: const [],))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
class StatesView extends StatefulWidget {
|
class StatesView extends StatefulWidget {
|
||||||
final List<TetrioPlayer> states;
|
final List<TetrioPlayer> states;
|
||||||
const StatesView({Key? key, required this.states}) : super(key: key);
|
const StatesView({super.key, required this.states});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => StatesState();
|
State<StatefulWidget> createState() => StatesState();
|
||||||
|
|
|
@ -20,7 +20,7 @@ late String _oldWindowTitle;
|
||||||
final NumberFormat _f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 4);
|
final NumberFormat _f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 4);
|
||||||
|
|
||||||
class TLLeaderboardView extends StatefulWidget {
|
class TLLeaderboardView extends StatefulWidget {
|
||||||
const TLLeaderboardView({Key? key}) : super(key: key);
|
const TLLeaderboardView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => TLLeaderboardState();
|
State<StatefulWidget> createState() => TLLeaderboardState();
|
||||||
|
@ -42,7 +42,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final t = Translations.of(context);
|
final t = Translations.of(context);
|
||||||
final NumberFormat _f2 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
|
final NumberFormat f2 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(t.tlLeaderboard),
|
title: Text(t.tlLeaderboard),
|
||||||
|
@ -175,11 +175,11 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Text((index+1).toString(), style: bigScreen ? const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28) : null),
|
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")),
|
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]}"),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text("${_f2.format(allPlayers[index].rating)} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null),
|
Text("${f2.format(allPlayers[index].rating)} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null),
|
||||||
Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 16),
|
Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 16),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -29,8 +29,7 @@ Duration framesToTime(int frames){
|
||||||
class TlMatchResultView extends StatefulWidget {
|
class TlMatchResultView extends StatefulWidget {
|
||||||
final TetraLeagueAlphaRecord record;
|
final TetraLeagueAlphaRecord record;
|
||||||
final String initPlayerId;
|
final String initPlayerId;
|
||||||
const TlMatchResultView({Key? key, required this.record, required this.initPlayerId})
|
const TlMatchResultView({super.key, required this.record, required this.initPlayerId});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => TlMatchResultState();
|
State<StatefulWidget> createState() => TlMatchResultState();
|
||||||
|
|
|
@ -13,7 +13,7 @@ final TetrioService teto = TetrioService();
|
||||||
late String oldWindowTitle;
|
late String oldWindowTitle;
|
||||||
|
|
||||||
class TrackedPlayersView extends StatefulWidget {
|
class TrackedPlayersView extends StatefulWidget {
|
||||||
const TrackedPlayersView({Key? key}) : super(key: key);
|
const TrackedPlayersView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => TrackedPlayersState();
|
State<StatefulWidget> createState() => TrackedPlayersState();
|
||||||
|
|
|
@ -37,7 +37,7 @@ class StatCellNum extends StatelessWidget {
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(text: intf.format(integer),
|
text: TextSpan(text: intf.format(integer),
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: fractionf.format(fraction).substring(1), style: TextStyle(fontSize: 16))
|
TextSpan(text: fractionf.format(fraction).substring(1), style: const TextStyle(fontSize: 16))
|
||||||
],
|
],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: "Eurostile Round Extended",
|
fontFamily: "Eurostile Round Extended",
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TLThingy extends StatefulWidget {
|
||||||
final bool showTitle;
|
final bool showTitle;
|
||||||
final bool bot;
|
final bool bot;
|
||||||
final double? topTR;
|
final double? topTR;
|
||||||
const TLThingy({Key? key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.topTR}) : super(key: key);
|
const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.topTR});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<TLThingy> createState() => _TLThingyState();
|
State<TLThingy> createState() => _TLThingyState();
|
||||||
|
|
|
@ -28,7 +28,7 @@ class UserThingy extends StatelessWidget {
|
||||||
final bool showStateTimestamp;
|
final bool showStateTimestamp;
|
||||||
final Function setState;
|
final Function setState;
|
||||||
|
|
||||||
const UserThingy({Key? key, required this.player, required this.showStateTimestamp, required this.setState}) : super(key: key);
|
const UserThingy({super.key, required this.player, required this.showStateTimestamp, required this.setState});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
Loading…
Reference in New Issue