Compare commits
2 Commits
cedb304c1a
...
9394b818cc
Author | SHA1 | Date |
---|---|---|
dan63047 | 9394b818cc | |
dan63047 | 751e7a7071 |
|
@ -1,13 +1,18 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:developer' as developer;
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tetra_stats/services/tetrio_crud.dart';
|
||||
import 'package:tetra_stats/views/customization_view.dart';
|
||||
import 'package:tetra_stats/views/ranks_averages_view.dart';
|
||||
import 'package:tetra_stats/views/sprint_and_blitz_averages.dart';
|
||||
import 'package:tetra_stats/views/tl_leaderboard_view.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
|
||||
|
@ -24,6 +29,38 @@ late SharedPreferences prefs;
|
|||
late TetrioService teto;
|
||||
ColorScheme sheme = const ColorScheme.dark(primary: Colors.cyanAccent, secondary: Colors.white);
|
||||
|
||||
Future<dynamic> computeIsolate(Future Function() function) async {
|
||||
final receivePort = ReceivePort();
|
||||
var rootToken = RootIsolateToken.instance!;
|
||||
await Isolate.spawn<_IsolateData>(
|
||||
_isolateEntry,
|
||||
_IsolateData(
|
||||
token: rootToken,
|
||||
function: function,
|
||||
answerPort: receivePort.sendPort,
|
||||
),
|
||||
);
|
||||
return await receivePort.first;
|
||||
}
|
||||
|
||||
void _isolateEntry(_IsolateData isolateData) async {
|
||||
BackgroundIsolateBinaryMessenger.ensureInitialized(isolateData.token);
|
||||
final answer = await isolateData.function();
|
||||
isolateData.answerPort.send(answer);
|
||||
}
|
||||
|
||||
class _IsolateData {
|
||||
final RootIsolateToken token;
|
||||
final Function function;
|
||||
final SendPort answerPort;
|
||||
|
||||
_IsolateData({
|
||||
required this.token,
|
||||
required this.function,
|
||||
required this.answerPort,
|
||||
});
|
||||
}
|
||||
|
||||
void setAccentColor(Color color){ // does this thing work??? yes??? no???
|
||||
sheme = ColorScheme.dark(primary: color, secondary: Colors.white);
|
||||
}
|
||||
|
@ -38,6 +75,26 @@ final router = GoRouter(
|
|||
GoRoute(
|
||||
path: 'settings',
|
||||
builder: (_, __) => const SettingsView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'customization',
|
||||
builder: (_, __) => const CustomizationView(),
|
||||
),
|
||||
]
|
||||
),
|
||||
GoRoute(
|
||||
path: "leaderboard",
|
||||
builder: (_, __) => const TLLeaderboardView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: "LBvalues",
|
||||
builder: (_, __) => const RankAveragesView(),
|
||||
),
|
||||
]
|
||||
),
|
||||
GoRoute(
|
||||
path: "LBvalues",
|
||||
builder: (_, __) => const RankAveragesView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'states',
|
||||
|
@ -48,9 +105,9 @@ final router = GoRouter(
|
|||
builder: (_, __) => const CalcView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'customization',
|
||||
builder: (_, __) => const CustomizationView(),
|
||||
),
|
||||
path: 'sprintAndBlitzAverages',
|
||||
builder: (_, __) => const SprintAndBlitzView(),
|
||||
)
|
||||
]
|
||||
),
|
||||
GoRoute( // that one intended for Android users, that can open https://ch.tetr.io/u/ links
|
||||
|
@ -92,10 +149,10 @@ void main() async {
|
|||
}
|
||||
|
||||
// I dont want to store old cache
|
||||
Timer.periodic(Duration(minutes: 5), (Timer timer) async {
|
||||
Timer.periodic(Duration(minutes: 5), (Timer timer) {
|
||||
teto.cacheRoutine();
|
||||
developer.log("Cache routine complete, next one in ${DateTime.now().add(Duration(minutes: 5))}", name: "main");
|
||||
if (prefs.getBool("updateInBG") == true) await teto.fetchTracked();
|
||||
// if (prefs.getBool("updateInBG") == true) teto.fetchTracked(); // TODO: Somehow avoid doing that in main isolate
|
||||
});
|
||||
|
||||
runApp(TranslationProvider(
|
||||
|
|
|
@ -8,5 +8,6 @@ final NumberFormat f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings
|
|||
final NumberFormat f3 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 3);
|
||||
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 f1 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 1);
|
||||
final NumberFormat f0 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode);
|
||||
final NumberFormat percentage = NumberFormat.percentPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
|
|
@ -0,0 +1,59 @@
|
|||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
|
||||
/// Returns string, that represents time difference between [dateTime] and now
|
||||
String relativeDateTime(DateTime dateTime){
|
||||
Duration difference = dateTime.difference(DateTime.now());
|
||||
bool inPast = difference.isNegative;
|
||||
Duration absDifference = difference.abs();
|
||||
double timeInterval;
|
||||
|
||||
// years
|
||||
timeInterval = absDifference.inSeconds / 31536000;
|
||||
if (timeInterval >= 100.0) {
|
||||
return inPast ? "${timeInterval.truncate()} years ago" : "in ${timeInterval.truncate()} years";
|
||||
} else if (timeInterval >= 10.0) {
|
||||
return inPast ? "${f1.format(timeInterval)} years ago" : "in ${f1.format(timeInterval)} years";
|
||||
} else if (timeInterval >= 1.0) {
|
||||
return inPast ? "${f2.format(timeInterval)} years ago" : "in ${f2.format(timeInterval)} years";
|
||||
}
|
||||
|
||||
// months
|
||||
timeInterval = absDifference.inSeconds / 2592000;
|
||||
if (timeInterval >= 10.0) {
|
||||
return inPast ? "${timeInterval.truncate()} months ago" : "in ${timeInterval.truncate()} months";
|
||||
} else if (timeInterval >= 1.0) {
|
||||
return inPast ? "${f1.format(timeInterval)} months ago" : "in ${f1.format(timeInterval)} months";
|
||||
}
|
||||
|
||||
// days
|
||||
timeInterval = absDifference.inSeconds / 86400;
|
||||
if (timeInterval >= 10.0) {
|
||||
return inPast ? "${timeInterval.truncate()} days ago" : "in ${timeInterval.truncate()} days";
|
||||
} else if (timeInterval >= 1.0) {
|
||||
return inPast ? "${f1.format(timeInterval)} days ago" : "in ${f1.format(timeInterval)} days";
|
||||
}
|
||||
|
||||
// hours
|
||||
timeInterval = absDifference.inSeconds / 3600;
|
||||
if (timeInterval >= 10.0) {
|
||||
return inPast ? "${timeInterval.truncate()} hours ago" : "in ${timeInterval.truncate()} hours";
|
||||
} else if (timeInterval >= 1.0) {
|
||||
return inPast ? "${f1.format(timeInterval)} hours ago" : "in ${f1.format(timeInterval)} hours";
|
||||
}
|
||||
|
||||
// minutes
|
||||
timeInterval = absDifference.inSeconds / 60;
|
||||
if (timeInterval >= 10.0) {
|
||||
return inPast ? "${timeInterval.truncate()} minutes ago" : "in ${timeInterval.truncate()} minutes";
|
||||
} else if (timeInterval >= 1.0) {
|
||||
return inPast ? "${f1.format(timeInterval)} minutes ago" : "in ${f1.format(timeInterval)} minutes";
|
||||
}
|
||||
|
||||
// seconds
|
||||
timeInterval = absDifference.inMilliseconds / 1000;
|
||||
if (timeInterval >= 10.0) {
|
||||
return inPast ? "${timeInterval.truncate()} seconds ago" : "in ${timeInterval.truncate()} seconds";
|
||||
} else {
|
||||
return inPast ? "${f1.format(timeInterval)} seconds ago" : "in ${f1.format(timeInterval)} seconds";
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import 'dart:io';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tetra_stats/views/settings_view.dart' show subtitleStyle;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tetra_stats/main.dart' show prefs;
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
|
@ -18,10 +18,10 @@ class CustomizationView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class CustomizationState extends State<CustomizationView> {
|
||||
late SharedPreferences prefs;
|
||||
late bool oskKagariGimmick;
|
||||
late bool sheetbotRadarGraphs;
|
||||
late int ratingMode;
|
||||
late int timestampMode;
|
||||
|
||||
void changeColor(Color color) {
|
||||
setState(() => pickerColor = color);
|
||||
|
@ -33,7 +33,7 @@ class CustomizationState extends State<CustomizationView> {
|
|||
windowManager.getTitle().then((value) => oldWindowTitle = value);
|
||||
windowManager.setTitle("Tetra Stats: ${t.settings}");
|
||||
}
|
||||
_getPreferences().then((value) => setState((){}));
|
||||
_getPreferences();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,7 @@ class CustomizationState extends State<CustomizationView> {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _getPreferences() async {
|
||||
prefs = await SharedPreferences.getInstance();
|
||||
void _getPreferences() {
|
||||
if (prefs.getBool("oskKagariGimmick") != null) {
|
||||
oskKagariGimmick = prefs.getBool("oskKagariGimmick")!;
|
||||
} else {
|
||||
|
@ -60,6 +59,11 @@ class CustomizationState extends State<CustomizationView> {
|
|||
} else {
|
||||
ratingMode = 0;
|
||||
}
|
||||
if (prefs.getInt("timestampMode") != null) {
|
||||
timestampMode = prefs.getInt("timestampMode")!;
|
||||
} else {
|
||||
timestampMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ThemeData getTheme(BuildContext context, Color color){
|
||||
|
@ -125,6 +129,23 @@ class CustomizationState extends State<CustomizationView> {
|
|||
oskKagariGimmick = value;
|
||||
});
|
||||
}),),
|
||||
ListTile(title: Text("Timestamps"),
|
||||
subtitle: Text(t.oskKagariDescription, style: subtitleStyle),
|
||||
trailing: DropdownButton(
|
||||
value: timestampMode,
|
||||
items: <DropdownMenuItem>[
|
||||
DropdownMenuItem(value: 0, child: Text("Absolute (GMT)")),
|
||||
DropdownMenuItem(value: 1, child: Text("Absolute (Local Time)")),
|
||||
DropdownMenuItem(value: 2, child: Text("Relative"))
|
||||
],
|
||||
onChanged: (dynamic value){
|
||||
prefs.setInt("timestampMode", value);
|
||||
setState(() {
|
||||
timestampMode = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(title: Text("Main representation of rating"),
|
||||
subtitle: Text(t.oskKagariDescription, style: subtitleStyle),
|
||||
trailing: DropdownButton(
|
||||
|
@ -141,13 +162,6 @@ class CustomizationState extends State<CustomizationView> {
|
|||
});
|
||||
},
|
||||
),
|
||||
// trailing: Switch(value: sheetbotRadarGraphs, onChanged: (bool value){
|
||||
// prefs.setBool("sheetbotRadarGraphs", value);
|
||||
// setState(() {
|
||||
// sheetbotRadarGraphs = value;
|
||||
// });
|
||||
// }
|
||||
// ),
|
||||
),
|
||||
ListTile(title: Text("Sheetbot-like behavior for radar graphs"),
|
||||
subtitle: Text(t.oskKagariDescription, style: subtitleStyle),
|
||||
|
|
|
@ -18,15 +18,13 @@ import 'package:tetra_stats/main.dart' show prefs, teto;
|
|||
import 'package:tetra_stats/services/crud_exceptions.dart';
|
||||
import 'package:tetra_stats/utils/numers_formats.dart';
|
||||
import 'package:tetra_stats/utils/text_shadow.dart';
|
||||
import 'package:tetra_stats/views/ranks_averages_view.dart' show RankAveragesView;
|
||||
import 'package:tetra_stats/views/sprint_and_blitz_averages.dart';
|
||||
import 'package:tetra_stats/views/tl_leaderboard_view.dart' show TLLeaderboardView;
|
||||
import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView;
|
||||
import 'package:tetra_stats/widgets/finesse_thingy.dart';
|
||||
import 'package:tetra_stats/widgets/lineclears_thingy.dart';
|
||||
import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart';
|
||||
import 'package:tetra_stats/widgets/search_box.dart';
|
||||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||
import 'package:tetra_stats/widgets/tl_thingy.dart';
|
||||
import 'package:tetra_stats/widgets/user_thingy.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
@ -41,7 +39,6 @@ List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS
|
|||
late ScrollController _scrollController;
|
||||
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
||||
final NumberFormat secs = NumberFormat("00.###", LocaleSettings.currentLocale.languageCode);
|
||||
final DateFormat _dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
|
||||
|
||||
class MainView extends StatefulWidget {
|
||||
|
@ -98,7 +95,6 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
bool _TLHistoryWasFetched = false;
|
||||
late TabController _tabController;
|
||||
late TabController _wideScreenTabController;
|
||||
late bool fixedScroll;
|
||||
|
||||
String get title => "Tetra Stats: $_titleNickname";
|
||||
|
||||
|
@ -652,12 +648,7 @@ class _NavDrawerState extends State<NavDrawer> {
|
|||
leading: const Icon(Icons.leaderboard),
|
||||
title: Text(t.tlLeaderboard),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const TLLeaderboardView(),
|
||||
),
|
||||
);
|
||||
context.go("/leaderboard");
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -666,12 +657,7 @@ class _NavDrawerState extends State<NavDrawer> {
|
|||
leading: const Icon(Icons.compress),
|
||||
title: Text(t.rankAveragesViewTitle),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const RankAveragesView(),
|
||||
),
|
||||
);
|
||||
context.go("/LBvalues");
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -680,12 +666,7 @@ class _NavDrawerState extends State<NavDrawer> {
|
|||
leading: const Icon(Icons.bar_chart),
|
||||
title: Text(t.sprintAndBlitsViewTitle),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const SprintAndBlitzView(),
|
||||
),
|
||||
);
|
||||
context.go("/sprintAndBlitzAverages");
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -767,7 +748,7 @@ class _TLRecords extends StatelessWidget {
|
|||
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}"),
|
||||
subtitle: Text(_dateFormat.format(data[index].timestamp)),
|
||||
subtitle: Text(timestamp(data[index].timestamp)),
|
||||
trailing: TrailingStats(
|
||||
data[index].endContext.firstWhere((element) => element.userId == userID).secondary,
|
||||
data[index].endContext.firstWhere((element) => element.userId == userID).tertiary,
|
||||
|
@ -930,7 +911,7 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
|||
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 20),
|
||||
),
|
||||
),
|
||||
Text(_gamesPlayedInsteadOfDateAndTime ? t.gamesPlayed(games: t.games(n: data.gamesPlayed)) : _dateFormat.format(data.timestamp))
|
||||
Text(_gamesPlayedInsteadOfDateAndTime ? t.gamesPlayed(games: t.games(n: data.gamesPlayed)) : timestamp(data.timestamp))
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -1086,7 +1067,7 @@ class _TwoRecordsThingy extends StatelessWidget {
|
|||
)),
|
||||
if (sprint!.rank != null) TextSpan(text: "№${sprint!.rank}", style: TextStyle(color: getColorOfRank(sprint!.rank!))),
|
||||
if (sprint!.rank != null) const TextSpan(text: " • "),
|
||||
TextSpan(text: _dateFormat.format(sprint!.timestamp!)),
|
||||
TextSpan(text: timestamp(sprint!.timestamp!)),
|
||||
]
|
||||
),
|
||||
),
|
||||
|
@ -1142,7 +1123,7 @@ class _TwoRecordsThingy extends StatelessWidget {
|
|||
else TextSpan(text: "${t.verdictGeneral(n: readableIntDifference(blitz!.endContext!.score, closestAverageBlitz.value), verdict: blitzBetterThanClosestAverage ? t.verdictBetter : t.verdictWorse, rank: closestAverageBlitz.key.toUpperCase())}\n", style: TextStyle(
|
||||
color: blitzBetterThanClosestAverage ? Colors.greenAccent : Colors.redAccent
|
||||
)),
|
||||
TextSpan(text: _dateFormat.format(blitz!.timestamp!)),
|
||||
TextSpan(text: timestamp(blitz!.timestamp!)),
|
||||
if (blitz!.rank != null) const TextSpan(text: " • "),
|
||||
if (blitz!.rank != null) TextSpan(text: "№${blitz!.rank}", style: TextStyle(color: getColorOfRank(blitz!.rank!))),
|
||||
]
|
||||
|
@ -1254,7 +1235,7 @@ class _RecordThingy extends StatelessWidget {
|
|||
)),
|
||||
if (record!.rank != null) TextSpan(text: "№${record!.rank}", style: TextStyle(color: getColorOfRank(record!.rank!))),
|
||||
if (record!.rank != null) const TextSpan(text: " • "),
|
||||
TextSpan(text: _dateFormat.format(record!.timestamp!)),
|
||||
TextSpan(text: timestamp(record!.timestamp!)),
|
||||
]
|
||||
),
|
||||
)
|
||||
|
@ -1368,7 +1349,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
]
|
||||
)
|
||||
),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
);
|
||||
case "personalbest":
|
||||
return ListTile(
|
||||
|
@ -1383,7 +1364,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
]
|
||||
)
|
||||
),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
leading: Image.asset(
|
||||
"res/icons/improvement-local.png",
|
||||
height: 48,
|
||||
|
@ -1405,7 +1386,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
]
|
||||
)
|
||||
),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
leading: Image.asset(
|
||||
"res/tetrio_badges/${news.data["type"]}.png",
|
||||
height: 48,
|
||||
|
@ -1427,7 +1408,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
]
|
||||
)
|
||||
),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
leading: Image.asset(
|
||||
"res/tetrio_tl_alpha_ranks/${news.data["rank"]}.png",
|
||||
height: 48,
|
||||
|
@ -1448,7 +1429,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
]
|
||||
)
|
||||
),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
leading: Image.asset(
|
||||
"res/icons/supporter-tag.png",
|
||||
height: 48,
|
||||
|
@ -1469,7 +1450,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
]
|
||||
)
|
||||
),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
leading: Image.asset(
|
||||
"res/icons/supporter-tag.png",
|
||||
height: 48,
|
||||
|
@ -1482,7 +1463,7 @@ class _OtherThingy extends StatelessWidget {
|
|||
default: // if type is unknown
|
||||
return ListTile(
|
||||
title: Text(t.newsParts.unknownNews(type: news.type)),
|
||||
subtitle: Text(_dateFormat.format(news.timestamp)),
|
||||
subtitle: Text(timestamp(news.timestamp)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import 'dart:io';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/main.dart' show packageInfo, teto;
|
||||
import 'package:tetra_stats/main.dart' show packageInfo, teto, prefs;
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/services/crud_exceptions.dart';
|
||||
import 'package:tetra_stats/utils/open_in_browser.dart';
|
||||
|
@ -24,7 +23,6 @@ class SettingsView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class SettingsState extends State<SettingsView> {
|
||||
late SharedPreferences prefs;
|
||||
String defaultNickname = "Checking...";
|
||||
late bool showPositions;
|
||||
late bool updateInBG;
|
||||
|
@ -46,8 +44,7 @@ class SettingsState extends State<SettingsView> {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _getPreferences() async {
|
||||
prefs = await SharedPreferences.getInstance();
|
||||
void _getPreferences() {
|
||||
showPositions = prefs.getBool("showPositions") ?? false;
|
||||
updateInBG = prefs.getBool("updateInBG") ?? false;
|
||||
_setDefaultNickname(prefs.getString("player"));
|
||||
|
@ -264,10 +261,10 @@ class SettingsState extends State<SettingsView> {
|
|||
subtitle: Text(t.customizationDescription, style: const TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey)),
|
||||
trailing: const Icon(Icons.arrow_right),
|
||||
onTap: () {
|
||||
context.go("/customization");
|
||||
context.go("/settings/customization");
|
||||
},),
|
||||
ListTile(title: Text("Update stats in the background"),
|
||||
subtitle: Text("While tetra stats is running, it can update stats of the current player when cache expires, as well, as tetra league stats of tracked players", style: const TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey)),
|
||||
subtitle: Text("While tetra stats is running, it can update stats of the current player when cache expires", style: const TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey)),
|
||||
trailing: Switch(value: updateInBG, onChanged: (bool value){
|
||||
prefs.setBool("updateInBG", value);
|
||||
setState(() {
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:tetra_stats/gen/strings.g.dart';
|
|||
import 'package:tetra_stats/main.dart' show teto;
|
||||
import 'package:tetra_stats/views/mathes_view.dart';
|
||||
import 'package:tetra_stats/views/state_view.dart';
|
||||
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
class StatesView extends StatefulWidget {
|
||||
|
@ -38,7 +39,6 @@ class StatesState extends State<StatesView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(t.statesViewTitle(number: widget.states.length, nickname: widget.states.last.username.toUpperCase())),
|
||||
|
@ -60,14 +60,14 @@ class StatesState extends State<StatesView> {
|
|||
itemCount: widget.states.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(dateFormat.format(widget.states[index].state)),
|
||||
title: Text(timestamp(widget.states[index].state)),
|
||||
subtitle: Text(t.statesViewEntry(level: widget.states[index].level.toStringAsFixed(2), gameTime: widget.states[index].gameTime, friends: widget.states[index].friendCount, rd: NumberFormat.compact().format(widget.states[index].tlSeason1.rd))),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.delete_forever),
|
||||
onPressed: () {
|
||||
DateTime nn = widget.states[index].state;
|
||||
teto.deleteState(widget.states[index]).then((value) => setState(() {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.stateRemoved(date: dateFormat.format(nn)))));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.stateRemoved(date: timestamp(nn)))));
|
||||
}));
|
||||
},
|
||||
),
|
||||
|
|
|
@ -174,8 +174,8 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
|||
prototypeItem: ListTile(
|
||||
leading: Text("0", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9)),
|
||||
title: Text("ehhh...", style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)),
|
||||
trailing: Container(height: bigScreen ? 48 : 36, width: 1,),
|
||||
subtitle: Text("eh..."),
|
||||
trailing: SizedBox(height: bigScreen ? 48 : 36, width: 1,),
|
||||
subtitle: const Text("eh..."),
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:tetra_stats/data_objects/tetrio_multiplayer_replay.dart';
|
|||
import 'package:tetra_stats/services/crud_exceptions.dart';
|
||||
import 'package:tetra_stats/views/compare_view.dart' show CompareThingy, CompareBoolThingy;
|
||||
import 'package:tetra_stats/widgets/list_tile_trailing_stats.dart';
|
||||
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||
import 'package:tetra_stats/widgets/vs_graphs.dart';
|
||||
import 'main_view.dart' show secs;
|
||||
import 'package:tetra_stats/main.dart' show teto;
|
||||
|
@ -15,11 +16,8 @@ import 'package:tetra_stats/data_objects/tetrio.dart';
|
|||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/utils/open_in_browser.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
// ignore: avoid_web_libraries_in_flutter
|
||||
// import 'dart:html' show AnchorElement, document;
|
||||
|
||||
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
int roundSelector = -1; // -1 = match averages, otherwise round number-1
|
||||
List<DropdownMenuItem> rounds = []; // index zero will be match stats
|
||||
bool timeWeightedStatsAvaliable = true;
|
||||
|
@ -50,7 +48,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
replayData = teto.analyzeReplay(widget.record.replayId, widget.record.replayAvalable);
|
||||
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS){
|
||||
windowManager.getTitle().then((value) => oldWindowTitle = value);
|
||||
windowManager.setTitle("Tetra Stats: ${widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username.toUpperCase()} ${t.vs} ${widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username.toUpperCase()} ${t.inTLmatch} ${dateFormat.format(widget.record.timestamp)}");
|
||||
windowManager.setTitle("Tetra Stats: ${widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username.toUpperCase()} ${t.vs} ${widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username.toUpperCase()} ${t.inTLmatch} ${timestamp(widget.record.timestamp)}");
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
@ -709,7 +707,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
final t = Translations.of(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("${widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username.toUpperCase()} ${t.vs} ${widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username.toUpperCase()} ${t.inTLmatch} ${dateFormat.format(widget.record.timestamp)}"),
|
||||
title: Text("${widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username.toUpperCase()} ${t.vs} ${widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username.toUpperCase()} ${t.inTLmatch} ${timestamp(widget.record.timestamp)}"),
|
||||
actions: [
|
||||
PopupMenuButton(
|
||||
enabled: widget.record.replayAvalable,
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:tetra_stats/gen/strings.g.dart';
|
|||
import 'package:tetra_stats/main.dart' show teto;
|
||||
import 'package:tetra_stats/utils/filesizes_converter.dart';
|
||||
import 'package:tetra_stats/views/states_view.dart';
|
||||
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
late String oldWindowTitle;
|
||||
|
@ -37,7 +38,6 @@ class TrackedPlayersState extends State<TrackedPlayersView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(t.trackedPlayersViewTitle),
|
||||
|
@ -109,7 +109,7 @@ class TrackedPlayersState extends State<TrackedPlayersView> {
|
|||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(t.trackedPlayersEntry(nickname: allPlayers[keys[index]]!.last.username, numberOfStates: allPlayers[keys[index]]!.length)),
|
||||
subtitle: Text(t.trackedPlayersDescription(firstStateDate: dateFormat.format(allPlayers[keys[index]]!.first.state), lastStateDate: dateFormat.format(allPlayers[keys[index]]!.last.state))),
|
||||
subtitle: Text(t.trackedPlayersDescription(firstStateDate: timestamp(allPlayers[keys[index]]!.first.state), lastStateDate: timestamp(allPlayers[keys[index]]!.last.state))),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.delete_forever),
|
||||
onPressed: () {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/main.dart';
|
||||
import 'package:tetra_stats/utils/relative_timestamps.dart';
|
||||
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
|
||||
String timestamp(DateTime dateTime){
|
||||
int timestampMode = prefs.getInt("timestampMode")??0;
|
||||
return timestampMode == 2 ? relativeDateTime(dateTime) : dateFormat.format(timestampMode == 1 ? dateTime.toLocal() : dateTime);
|
||||
}
|
||||
|
||||
// class TextTimestamp extends StatelessWidget{
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// // TODO: implement build
|
||||
// return;
|
||||
// }
|
||||
|
||||
// }
|
|
@ -3,18 +3,17 @@ import 'package:intl/intl.dart';
|
|||
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/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';
|
||||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||
import 'package:tetra_stats/widgets/tl_progress_bar.dart';
|
||||
import 'package:tetra_stats/widgets/tl_rating_thingy.dart';
|
||||
|
||||
|
||||
var intFDiff = NumberFormat("+#,###;-#,###");
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
|
||||
class TLThingy extends StatefulWidget {
|
||||
final TetraLeagueAlpha tl;
|
||||
|
@ -69,7 +68,7 @@ class _TLThingyState extends State<TLThingy> {
|
|||
return Column(
|
||||
children: [
|
||||
if (widget.showTitle) Text(t.tetraLeague, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||
if (oldTl != null) Text(t.comparingWith(newDate: dateFormat.format(currentTl.timestamp), oldDate: dateFormat.format(oldTl!.timestamp)),
|
||||
if (oldTl != null) Text(t.comparingWith(newDate: timestamp(currentTl.timestamp), oldDate: timestamp(oldTl!.timestamp)),
|
||||
textAlign: TextAlign.center,),
|
||||
if (oldTl != null) RangeSlider(values: _currentRangeValues, max: widget.states.length.toDouble(),
|
||||
labels: RangeLabels(
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:intl/intl.dart';
|
|||
import 'package:tetra_stats/utils/text_shadow.dart';
|
||||
import 'dart:developer' as developer;
|
||||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||
|
||||
const Map<int, double> xpTableScuffed = { // level: xp required
|
||||
05000: 67009018.4885772,
|
||||
|
@ -36,7 +37,6 @@ class UserThingy extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
return LayoutBuilder(builder: (context, constraints) {
|
||||
bool bigScreen = constraints.maxWidth > 768;
|
||||
double bannerHeight = bigScreen ? 240 : 120;
|
||||
|
@ -126,7 +126,7 @@ class UserThingy extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
showStateTimestamp
|
||||
? Text(t.fetchDate(date: dateFormat.format(player.state)))
|
||||
? Text(t.fetchDate(date: timestamp(player.state)))
|
||||
: Wrap(direction: Axis.horizontal, alignment: WrapAlignment.center, spacing: 25, crossAxisAlignment: WrapCrossAlignment.start, children: [
|
||||
FutureBuilder(
|
||||
future: teto.isPlayerTracking(player.userId),
|
||||
|
@ -340,7 +340,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!)}'}"),
|
||||
TextSpan(text: "${t.playerRole[player.role]}${t.playerRoleAccount}${player.registrationTime == null ? t.wasFromBeginning : '${t.created} ${timestamp(player.registrationTime!)}'}"),
|
||||
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))
|
||||
|
@ -386,7 +386,7 @@ class UserThingy extends StatelessWidget {
|
|||
children: [
|
||||
Image.asset("res/tetrio_badges/${badge.badgeId}.png"),
|
||||
Text(badge.ts != null
|
||||
? t.obtainDate(date: dateFormat.format(badge.ts!))
|
||||
? t.obtainDate(date: timestamp(badge.ts!))
|
||||
: t.assignedManualy),
|
||||
],
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue