From ba78d50f216f6b69059c7f357e920bfad40a998c Mon Sep 17 00:00:00 2001 From: dan63047 Date: Wed, 2 Oct 2024 00:46:43 +0300 Subject: [PATCH] Sorting functions for LB's (works kinda meh...) --- .../tetrio_players_leaderboard.dart | 19 ++++++ lib/gen/strings.g.dart | 10 ++-- lib/services/tetrio_crud.dart | 5 +- lib/views/main_view_tiles.dart | 60 ++++++++++++++++--- res/i18n/strings.i18n.json | 2 +- res/i18n/strings_ru.i18n.json | 2 +- 6 files changed, 80 insertions(+), 18 deletions(-) diff --git a/lib/data_objects/tetrio_players_leaderboard.dart b/lib/data_objects/tetrio_players_leaderboard.dart index 1d2305d..91e3336 100644 --- a/lib/data_objects/tetrio_players_leaderboard.dart +++ b/lib/data_objects/tetrio_players_leaderboard.dart @@ -38,6 +38,25 @@ class TetrioPlayersLeaderboard { return lb; } + List getStatRankingFromLB(Stats stat, {bool reversed = false, String country = ""}){ + List lb = List.from(leaderboard); + if (country.isNotEmpty){ + lb.removeWhere((element) => element.country != country); + } + lb.sort(((a, b) { + if (a.getStatByEnum(stat).isNaN) return 1; + if (b.getStatByEnum(stat).isNaN) return -1; + if (a.getStatByEnum(stat) > b.getStatByEnum(stat)){ + return reversed ? 1 : -1; + }else if (a.getStatByEnum(stat) == b.getStatByEnum(stat)){ + return 0; + }else{ + return reversed ? -1 : 1; + } + })); + return lb; + } + List getAverageOfRank(String rank){ // i tried to refactor it and that's was terrible if (rank.isNotEmpty && !rankCutoffs.keys.contains(rank)) throw Exception("Invalid rank"); List filtredLeaderboard = List.from(leaderboard); diff --git a/lib/gen/strings.g.dart b/lib/gen/strings.g.dart index 12ea442..c34c1f6 100644 --- a/lib/gen/strings.g.dart +++ b/lib/gen/strings.g.dart @@ -6,7 +6,7 @@ /// Locales: 3 /// Strings: 1818 (606 per locale) /// -/// Built on 2024-09-12 at 20:23 UTC +/// Built on 2024-09-30 at 21:23 UTC // coverage:ignore-file // ignore_for_file: type=lint @@ -396,7 +396,7 @@ class Translations implements BaseTranslations { late final _StringsPopupActionsEn popupActions = _StringsPopupActionsEn._(_root); late final _StringsErrorsEn errors = _StringsErrorsEn._(_root); Map get countries => { - '': 'Not selected', + '': 'Worldwide', 'AF': 'Afghanistan', 'AX': 'Åland Islands', 'AL': 'Albania', @@ -1108,7 +1108,7 @@ class _StringsRu implements Translations { @override late final _StringsPopupActionsRu popupActions = _StringsPopupActionsRu._(_root); @override late final _StringsErrorsRu errors = _StringsErrorsRu._(_root); @override Map get countries => { - '': 'Не выбрана', + '': 'Во всём мире', 'AF': 'Афганистан', 'AX': 'Аландские острова', 'AL': 'Албания', @@ -2628,7 +2628,7 @@ extension on Translations { case 'errors.replayAlreadySaved': return 'Replay already saved'; case 'errors.replayExpired': return 'Replay expired and not available anymore'; case 'errors.replayRejected': return 'Third party API blocked your IP address'; - case 'countries.': return 'Not selected'; + case 'countries.': return 'Worldwide'; case 'countries.AF': return 'Afghanistan'; case 'countries.AX': return 'Åland Islands'; case 'countries.AL': return 'Albania'; @@ -3256,7 +3256,7 @@ extension on _StringsRu { case 'errors.replayAlreadySaved': return 'Повтор уже сохранён'; case 'errors.replayExpired': return 'Повтор истёк и больше недоступен'; case 'errors.replayRejected': return 'Стороннее API заблокировало ваш IP адрес'; - case 'countries.': return 'Не выбрана'; + case 'countries.': return 'Во всём мире'; case 'countries.AF': return 'Афганистан'; case 'countries.AX': return 'Аландские острова'; case 'countries.AL': return 'Албания'; diff --git a/lib/services/tetrio_crud.dart b/lib/services/tetrio_crud.dart index f85ed42..c74c16b 100644 --- a/lib/services/tetrio_crud.dart +++ b/lib/services/tetrio_crud.dart @@ -853,14 +853,15 @@ class TetrioService extends DB { } } - Future> fetchTetrioRecordsLeaderboard({String? prisecter, String? lb}) async{ + Future> fetchTetrioRecordsLeaderboard({String? prisecter, String? lb, String? country}) async{ Uri url; if (kIsWeb) { url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLLeaderboard"}); } else { url = Uri.https('ch.tetr.io', 'api/records/${lb??"40l_global"}', { "limit": "100", - if (prisecter != null) "after": prisecter + if (prisecter != null) "after": prisecter, + if (country != null) "country": country }); } try{ diff --git a/lib/views/main_view_tiles.dart b/lib/views/main_view_tiles.dart index 211567e..4344d4a 100644 --- a/lib/views/main_view_tiles.dart +++ b/lib/views/main_view_tiles.dart @@ -1099,6 +1099,10 @@ class _DestinationLeaderboardsState extends State { List list = []; bool _isFetchingData = false; String? prisecter; + List _countries = [for (MapEntry e in t.countries.entries) DropdownMenuEntry(value: e.key, label: e.value)]; + List _stats = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuEntry(value: e.key, label: e.value)]; + String? _country; + Stats stat = Stats.tr; Future _fetchData() async { if (_isFetchingData) { @@ -1110,14 +1114,14 @@ class _DestinationLeaderboardsState extends State { setState(() {}); final items = switch(_currentLb){ - Leaderboards.tl => await teto.fetchTetrioLeaderboard(prisecter: prisecter), - Leaderboards.fullTL => (await teto.fetchTLLeaderboard()).leaderboard, - Leaderboards.xp => await teto.fetchTetrioLeaderboard(prisecter: prisecter, lb: "xp"), - Leaderboards.ar => await teto.fetchTetrioLeaderboard(prisecter: prisecter, lb: "ar"), - Leaderboards.sprint => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter), - Leaderboards.blitz => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "blitz_global"), - Leaderboards.zenith => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "zenith_global"), - Leaderboards.zenithex => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "zenithex_global"), + Leaderboards.tl => await teto.fetchTetrioLeaderboard(prisecter: prisecter, country: _country), + Leaderboards.fullTL => (await teto.fetchTLLeaderboard()).getStatRankingFromLB(stat, country: _country??""), + Leaderboards.xp => await teto.fetchTetrioLeaderboard(prisecter: prisecter, lb: "xp", country: _country), + Leaderboards.ar => await teto.fetchTetrioLeaderboard(prisecter: prisecter, lb: "ar", country: _country), + Leaderboards.sprint => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, country: _country), + Leaderboards.blitz => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "blitz_global", country: _country), + Leaderboards.zenith => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "zenith_global", country: _country), + Leaderboards.zenithex => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "zenithex_global", country: _country), }; list.addAll(items); @@ -1211,6 +1215,44 @@ class _DestinationLeaderboardsState extends State { return Column( children: [ Text(leaderboards[_currentLb]!, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, height: 0.9)), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + DropdownMenu( + leadingIcon: Icon(Icons.public), + inputDecorationTheme: InputDecorationTheme( + isDense: true, + ), + textStyle: TextStyle(fontSize: 14, height: 0.9), + dropdownMenuEntries: _countries, + initialSelection: "", + onSelected: ((value) { + _country = value as String?; + list.clear(); + prisecter = null; + _isFetchingData = false; + setState((){_fetchData();}); + }) + ), + if (_currentLb == Leaderboards.fullTL) SizedBox(width: 5.0), + if (_currentLb == Leaderboards.fullTL) DropdownMenu( + leadingIcon: Icon(Icons.sort), + inputDecorationTheme: InputDecorationTheme( + isDense: true, + ), + textStyle: TextStyle(fontSize: 14, height: 0.9), + dropdownMenuEntries: _stats, + initialSelection: stat, + onSelected: ((value) { + stat = value; + list.clear(); + prisecter = null; + _isFetchingData = false; + setState((){_fetchData();}); + }) + ) + ], + ), const Divider(color: Color.fromARGB(50, 158, 158, 158)), Expanded( child: ListView.builder( @@ -4257,7 +4299,7 @@ class FutureError extends StatelessWidget{ Text(snapshot.error.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), Padding( padding: const EdgeInsets.only(top: 8.0), - child: Text(snapshot.stackTrace.toString(), textAlign: TextAlign.center), + child: Text(snapshot.stackTrace.toString(), textAlign: TextAlign.left, style: TextStyle(fontFamily: "Monospace")), ), Spacer() ], diff --git a/res/i18n/strings.i18n.json b/res/i18n/strings.i18n.json index cabae6f..6c75715 100644 --- a/res/i18n/strings.i18n.json +++ b/res/i18n/strings.i18n.json @@ -377,7 +377,7 @@ "replayRejected": "Third party API blocked your IP address" }, "countries(map)": { - "": "Not selected", + "": "Worldwide", "AF": "Afghanistan", "AX": "\u00c5land Islands", diff --git a/res/i18n/strings_ru.i18n.json b/res/i18n/strings_ru.i18n.json index d29f98e..9b538d0 100644 --- a/res/i18n/strings_ru.i18n.json +++ b/res/i18n/strings_ru.i18n.json @@ -377,7 +377,7 @@ "replayRejected": "Стороннее API заблокировало ваш IP адрес" }, "countries(map)": { - "": "Не выбрана", + "": "Во всём мире", "AF": "Афганистан", "AX": "Аландские острова",