diff --git a/lib/data_objects/tetrio.dart b/lib/data_objects/tetrio.dart index 3e6d1da..ae5e0ee 100644 --- a/lib/data_objects/tetrio.dart +++ b/lib/data_objects/tetrio.dart @@ -639,7 +639,6 @@ class EstTr { final double _apm; final double _pps; final double _vs; - final double _rd; final double _app; final double _dss; final double _dsp; @@ -649,15 +648,11 @@ class EstTr { late double statrank; late double estglicko; - EstTr(this._apm, this._pps, this._vs, this._rd, this._app, this._dss, this._dsp, this._gbe) { + EstTr(this._apm, this._pps, this._vs, this._app, this._dss, this._dsp, this._gbe) { srarea = (_apm * 0) + (_pps * 135) + (_vs * 0) + (_app * 290) + (_dss * 0) + (_dsp * 700) + (_gbe * 0); statrank = 11.2 * atan((srarea - 93) / 130) + 1; if (statrank <= 0) statrank = 0.001; estglicko = (4.0867 * srarea + 186.68); - // double temp = (1500 - estglicko) * pi; - // double temp2 = pow((15.9056943314 * (pow(_rd, 2)) + 3527584.25978), 0.5) as double; - // double temp3 = 1 + pow(10, (temp / temp2)) as double; - //esttr = 25000 / temp3; double ntemp = _pps*(150+(((_vs/_apm) - 1.66)*35))+_app*290+_dsp*700; esttr = 25000 / ( @@ -821,8 +816,8 @@ class EndContextMulti { extraTracking = json['points']['extraAvgTracking']['aggregatestats___vsscore'].map((e) => e.toDouble()).toList(); nerdStats = NerdStats(secondary, tertiary, extra); nerdStatsTracking = [for (int i = 0; i < secondaryTracking.length; i++) NerdStats(secondaryTracking[i], tertiaryTracking[i], extraTracking[i])]; - estTr = EstTr(secondary, tertiary, extra, noTrRd, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe); - estTrTracking = [for (int i = 0; i < secondaryTracking.length; i++) EstTr(secondaryTracking[i], tertiaryTracking[i], extraTracking[i], noTrRd, nerdStatsTracking[i].app, nerdStatsTracking[i].dss, nerdStatsTracking[i].dsp, nerdStatsTracking[i].gbe)]; + estTr = EstTr(secondary, tertiary, extra, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe); + estTrTracking = [for (int i = 0; i < secondaryTracking.length; i++) EstTr(secondaryTracking[i], tertiaryTracking[i], extraTracking[i], nerdStatsTracking[i].app, nerdStatsTracking[i].dss, nerdStatsTracking[i].dsp, nerdStatsTracking[i].gbe)]; playstyle = Playstyle(secondary, tertiary, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank); playstyleTracking = [for (int i = 0; i < secondaryTracking.length; i++) Playstyle(secondaryTracking[i], tertiaryTracking[i], nerdStatsTracking[i].app, nerdStatsTracking[i].vsapm, nerdStatsTracking[i].dsp, nerdStatsTracking[i].gbe, estTrTracking[i].srarea, estTrTracking[i].statrank)]; } @@ -890,7 +885,7 @@ class TetraLeagueAlpha { this.vs, this.records}){ nerdStats = (apm != null && pps != null && vs != null) ? NerdStats(apm!, pps!, vs!) : null; - estTr = (nerdStats != null) ? EstTr(apm!, pps!, vs!, (rd != null) ? rd! : 69, nerdStats!.app, nerdStats!.dss, nerdStats!.dsp, nerdStats!.gbe) : null; + estTr = (nerdStats != null) ? EstTr(apm!, pps!, vs!, nerdStats!.app, nerdStats!.dss, nerdStats!.dsp, nerdStats!.gbe) : null; playstyle =(nerdStats != null) ? Playstyle(apm!, pps!, nerdStats!.app, nerdStats!.vsapm, nerdStats!.dsp, nerdStats!.gbe, estTr!.srarea, estTr!.statrank) : null; } @@ -918,7 +913,7 @@ class TetraLeagueAlpha { nextAt = json['next_at'] ?? -1; percentileRank = json['percentile_rank'] ?? rank; nerdStats = (apm != null && pps != null && vs != null) ? NerdStats(apm!, pps!, vs!) : null; - estTr = (nerdStats != null) ? EstTr(apm!, pps!, vs!, (rd != null) ? rd! : 69, nerdStats!.app, nerdStats!.dss, nerdStats!.dsp, nerdStats!.gbe) : null; + estTr = (nerdStats != null) ? EstTr(apm!, pps!, vs!, nerdStats!.app, nerdStats!.dss, nerdStats!.dsp, nerdStats!.gbe) : null; playstyle = (nerdStats != null) ? Playstyle(apm!, pps!, nerdStats!.app, nerdStats!.vsapm, nerdStats!.dsp, nerdStats!.gbe, estTr!.srarea, estTr!.statrank) : null; } @@ -1769,7 +1764,7 @@ class TetrioPlayerFromLeaderboard { vs = json['league']['vs'].toDouble(); decaying = json['league']['decaying']; nerdStats = NerdStats(apm, pps, vs); - estTr = EstTr(apm, pps, vs, rd, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe); + estTr = EstTr(apm, pps, vs, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe); playstyle = Playstyle(apm, pps, nerdStats.app, nerdStats.vsapm, nerdStats.dsp, nerdStats.gbe, estTr.srarea, estTr.statrank); } diff --git a/lib/main.dart b/lib/main.dart index d6d0222..e9e55fd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.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'; import 'package:tetra_stats/gen/strings.g.dart'; @@ -21,6 +22,10 @@ void main() async { databaseFactory = databaseFactoryFfi; } WidgetsFlutterBinding.ensureInitialized(); + await WindowManager.instance.ensureInitialized(); + windowManager.waitUntilReadyToShow().then((_) async { + await windowManager.setTitle('Tetra Stats'); + }); prefs = await SharedPreferences.getInstance(); String? locale = prefs.getString("locale"); if (locale == null){ diff --git a/lib/services/tetrio_crud.dart b/lib/services/tetrio_crud.dart index d48d884..ffe29ec 100644 --- a/lib/services/tetrio_crud.dart +++ b/lib/services/tetrio_crud.dart @@ -54,6 +54,7 @@ class TetrioService extends DB { final Map> _recordsCache = {}; final Map _leaderboardsCache = {}; final Map> _newsCache = {}; + final Map> _topTRcache = {}; final Map _tlStreamsCache = {}; // i'm trying to respect oskware api It should look something like {"cached_until": TetrioPlayer} final client = UserAgentClient("ebany u rot yatogo kazino blyat' (Tetra Stats v1.2.4 dev build)", http.Client()); static final TetrioService _shared = TetrioService._sharedInstance(); @@ -105,6 +106,58 @@ class TetrioService extends DB { } } + Future fetchTopTR(String id) async { + try{ + var cached = _topTRcache.entries.firstWhere((element) => element.value.keys.first == id); + if (DateTime.fromMillisecondsSinceEpoch(int.parse(cached.key.toString()), isUtc: true).isAfter(DateTime.now())){ + developer.log("fetchTopTR: Top TR retrieved from cache, that expires ${DateTime.fromMillisecondsSinceEpoch(int.parse(cached.key.toString()), isUtc: true)}", name: "services/tetrio_crud"); + return cached.value.values.first; + }else{ + _topTRcache.remove(cached.key); + developer.log("fetchTopTR: Top TR expired (${DateTime.fromMillisecondsSinceEpoch(int.parse(cached.key.toString()), isUtc: true)})", name: "services/tetrio_crud"); + } + }catch(e){ + developer.log("fetchTopTR: Trying to retrieve Top TR", name: "services/tetrio_crud"); + } + + Uri url; + if (kIsWeb) { + url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLHistory", "user": id}); + } else { + url = Uri.https('api.p1nkl0bst3r.xyz', 'toptr/$id'); + } + try{ + final response = await client.get(url); + + switch (response.statusCode) { + case 200: + _topTRcache[(DateTime.now().millisecondsSinceEpoch + 300000).toString()] = {id: double.tryParse(response.body)}; + return double.tryParse(response.body); + case 404: + developer.log("fetchTopTR: Probably, player doesn't have top TR", name: "services/tetrio_crud", error: response.statusCode); + _topTRcache[(DateTime.now().millisecondsSinceEpoch + 300000).toString()] = {id: null}; + return null; + case 403: + throw P1nkl0bst3rForbidden(); + case 429: + throw P1nkl0bst3rTooManyRequests(); + case 418: + throw TetrioOskwareBridgeProblem(); + case 500: + case 502: + case 503: + case 504: + throw P1nkl0bst3rInternalProblem(); + default: + developer.log("fetchTopTR: Failed to fetch top TR", name: "services/tetrio_crud", error: response.statusCode); + throw ConnectionIssue(response.statusCode, response.reasonPhrase??"No reason"); + } + } on http.ClientException catch (e, s) { + developer.log("$e, $s"); + throw http.ClientException(e.message, e.uri); + } + } + Future> fetchAndsaveTLHistory(String id) async { Uri url; if (kIsWeb) { @@ -238,7 +291,6 @@ class TetrioService extends DB { } } - // TODO: Future> getNews(String userID) async Future> fetchNews(String userID) async{ try{ var cached = _newsCache.entries.firstWhere((element) => element.value[0].stream == "user_$userID"); diff --git a/lib/views/calc_view.dart b/lib/views/calc_view.dart index b3aee1c..ba2cb0d 100644 --- a/lib/views/calc_view.dart +++ b/lib/views/calc_view.dart @@ -42,7 +42,7 @@ class CalcState extends State { vs = double.tryParse(vsController.text); if (apm != null && pps != null && vs != null) { nerdStats = NerdStats(apm!, pps!, vs!); - estTr = EstTr(apm!, pps!, vs!, 60.9, nerdStats!.app, nerdStats!.dss, nerdStats!.dsp, nerdStats!.gbe); + estTr = EstTr(apm!, pps!, vs!, nerdStats!.app, nerdStats!.dss, nerdStats!.dsp, nerdStats!.gbe); playstyle = Playstyle(apm!, pps!, nerdStats!.app, nerdStats!.vsapm, nerdStats!.dsp, nerdStats!.gbe, estTr!.srarea, estTr!.statrank); setState(() {}); } else { @@ -124,7 +124,7 @@ class CalcState extends State { _ListEntry(value: estTr!.esttr, label: t.statCellNum.estOfTR, fractionDigits: 3), Wrap( direction: Axis.horizontal, - alignment: WrapAlignment.spaceAround, + alignment: WrapAlignment.center, spacing: 25, crossAxisAlignment: WrapCrossAlignment.start, clipBehavior: Clip.hardEdge, diff --git a/lib/views/compare_view.dart b/lib/views/compare_view.dart index a93d729..ae889a7 100644 --- a/lib/views/compare_view.dart +++ b/lib/views/compare_view.dart @@ -642,7 +642,7 @@ class CompareState extends State { ), Wrap( direction: Axis.horizontal, - alignment: WrapAlignment.spaceAround, + alignment: WrapAlignment.center, spacing: 25, crossAxisAlignment: WrapCrossAlignment.start, clipBehavior: Clip.hardEdge, diff --git a/lib/views/main_view.dart b/lib/views/main_view.dart index d8da28f..c180daf 100644 --- a/lib/views/main_view.dart +++ b/lib/views/main_view.dart @@ -12,12 +12,14 @@ import 'package:tetra_stats/data_objects/tetrio.dart'; import 'package:tetra_stats/gen/strings.g.dart'; import 'package:tetra_stats/services/tetrio_crud.dart'; import 'package:tetra_stats/services/crud_exceptions.dart'; -import 'package:tetra_stats/views/ranks_averages_view.dart'; +import 'package:tetra_stats/views/ranks_averages_view.dart' show RankAveragesView; 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/stat_sell_num.dart'; import 'package:tetra_stats/widgets/tl_thingy.dart'; import 'package:tetra_stats/widgets/user_thingy.dart'; +import 'package:window_manager/window_manager.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; Future me = Future.delayed(const Duration(seconds: 60), () => [null, null, null, null, null, null]); String _searchFor = "6098518e3d5155e6ec429cdc"; @@ -136,10 +138,25 @@ class _MainState extends State with SingleTickerProviderStateMixin { } _searchFor = me.userId; setState((){_titleNickname = me.username;}); - List requests = await Future.wait([teto.getTLStream(_searchFor), teto.fetchRecords(_searchFor), teto.fetchNews(_searchFor)]); - TetraLeagueAlphaStream tlStream = requests[0] as TetraLeagueAlphaStream; - Map records = requests[1] as Map; - List news = requests[2] as List; + await windowManager.setTitle('Tetra Stats: $_titleNickname'); //TODO: Change window title on every view + late List requests; + late TetraLeagueAlphaStream tlStream; + late Map records; + late List news; + late double? topTR; + if (me.tlSeason1.gamesPlayed > 9) { + requests = await Future.wait([teto.getTLStream(_searchFor), teto.fetchRecords(_searchFor), teto.fetchNews(_searchFor), teto.fetchTopTR(_searchFor)]); + tlStream = requests[0] as TetraLeagueAlphaStream; + records = requests[1] as Map; + news = requests[2] as List; + topTR = requests[3] as double?; + }else{ + requests = await Future.wait([teto.getTLStream(_searchFor), teto.fetchRecords(_searchFor), teto.fetchNews(_searchFor)]); + tlStream = requests[0] as TetraLeagueAlphaStream; + records = requests[1] as Map; + news = requests[2] as List; + topTR = null; + } List tlMatches = []; bool isTracking = await teto.isPlayerTracking(me.userId); List states = []; @@ -191,7 +208,7 @@ class _MainState extends State with SingleTickerProviderStateMixin { DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.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.timestamp.millisecondsSinceEpoch.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))), ]; - return [me, records, states, tlMatches, compareWith, isTracking, news]; + return [me, records, states, tlMatches, compareWith, isTracking, news, topTR]; } void _justUpdate() { @@ -330,24 +347,12 @@ class _MainState extends State with SingleTickerProviderStateMixin { body: TabBarView( controller: _tabController, children: [ - TLThingy( - tl: snapshot.data![0].tlSeason1, - userID: snapshot.data![0].userId, - oldTl: snapshot.data![4]), + TLThingy(tl: snapshot.data![0].tlSeason1, userID: snapshot.data![0].userId, oldTl: snapshot.data![4], topTR: snapshot.data![7]), _TLRecords(userID: snapshot.data![0].userId, data: snapshot.data![3]), _History(states: snapshot.data![2], update: _justUpdate), - _RecordThingy( - record: (snapshot.data![1]['sprint'].isNotEmpty) - ? snapshot.data![1]['sprint'][0] - : null), - _RecordThingy( - record: (snapshot.data![1]['blitz'].isNotEmpty) - ? snapshot.data![1]['blitz'][0] - : null), - _OtherThingy( - zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, - distinguishment: snapshot.data![0].distinguishment, - newsletter: snapshot.data![6],) + _RecordThingy(record: (snapshot.data![1]['sprint'].isNotEmpty) ? snapshot.data![1]['sprint'][0] : null), + _RecordThingy(record: (snapshot.data![1]['blitz'].isNotEmpty) ? snapshot.data![1]['blitz'][0] : null), + _OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],) ], ), ), @@ -466,7 +471,7 @@ class _NavDrawerState extends State { final allPlayers = (snapshot.data != null) ? snapshot.data as Map> : >{}; - List keys = allPlayers.keys.toList().reversed.toList(); // this is so dumb + List keys = allPlayers.keys.toList(); return NestedScrollView( headerSliverBuilder: (context, value) { return [ @@ -521,9 +526,9 @@ class _NavDrawerState extends State { itemBuilder: (context, index) { return ListTile( title: Text( - allPlayers[keys[index]]?.last.username as String), + allPlayers[keys[allPlayers.length-1-index]]?.last.username as String), onTap: () { - widget.changePlayer(keys[index]); + widget.changePlayer(keys[allPlayers.length-1-index]); Navigator.of(context).pop(); }, ); @@ -966,6 +971,14 @@ class _OtherThingy extends StatelessWidget { ) ), subtitle: Text(dateFormat.format(news.timestamp)), + leading: Image.asset( + "res/icons/improvement-local.png", + height: 48, + width: 48, + errorBuilder: (context, error, stackTrace) { + return Image.asset("res/icons/kagari.png", height: 64, width: 64); + }, + ), ); case "badge": return ListTile( @@ -980,6 +993,14 @@ class _OtherThingy extends StatelessWidget { ) ), subtitle: Text(dateFormat.format(news.timestamp)), + leading: Image.asset( + "res/tetrio_badges/${news.data["type"]}.png", + height: 48, + width: 48, + errorBuilder: (context, error, stackTrace) { + return Image.asset("res/icons/kagari.png", height: 64, width: 64); + }, + ), ); case "rankup": return ListTile( @@ -994,32 +1015,56 @@ class _OtherThingy extends StatelessWidget { ) ), subtitle: Text(dateFormat.format(news.timestamp)), + leading: Image.asset( + "res/tetrio_tl_alpha_ranks/${news.data["rank"]}.png", + height: 48, + width: 48, + errorBuilder: (context, error, stackTrace) { + return Image.asset("res/icons/kagari.png", height: 64, width: 64); + }, + ), ); case "supporter": return ListTile( title: RichText( text: TextSpan( - style: TextStyle(fontFamily: 'Eurostile Round', fontSize: 16), + style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16), text: t.newsParts.supporterStart, children: [ - TextSpan(text: t.newsParts.tetoSupporter, style: TextStyle(fontWeight: FontWeight.bold)) + TextSpan(text: t.newsParts.tetoSupporter, style: const TextStyle(fontWeight: FontWeight.bold)) ] ) ), subtitle: Text(dateFormat.format(news.timestamp)), + leading: Image.asset( + "res/icons/supporter-tag.png", + height: 48, + width: 48, + errorBuilder: (context, error, stackTrace) { + return Image.asset("res/icons/kagari.png", height: 64, width: 64); + }, + ), ); case "supporter_gift": return ListTile( title: RichText( text: TextSpan( - style: TextStyle(fontFamily: 'Eurostile Round', fontSize: 16), + style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16), text: t.newsParts.supporterGiftStart, children: [ - TextSpan(text: t.newsParts.tetoSupporter, style: TextStyle(fontWeight: FontWeight.bold)) + TextSpan(text: t.newsParts.tetoSupporter, style: const TextStyle(fontWeight: FontWeight.bold)) ] ) ), subtitle: Text(dateFormat.format(news.timestamp)), + leading: Image.asset( + "res/icons/supporter-tag.png", + height: 48, + width: 48, + errorBuilder: (context, error, stackTrace) { + return Image.asset("res/icons/kagari.png", height: 64, width: 64); + }, + ), ); default: return ListTile( @@ -1057,11 +1102,11 @@ class _OtherThingy extends StatelessWidget { ), if (bio != null) Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 48), + padding: const EdgeInsets.fromLTRB(8, 0, 8, 48), child: Column( children: [ Text(t.bio, style: TextStyle(fontFamily: "Eurostile Round Extended",fontSize: bigScreen ? 42 : 28)), - Text(bio!, style: const TextStyle(fontSize: 18)), + MarkdownBody(data: bio!, styleSheet: MarkdownStyleSheet(textScaleFactor: 1.5, textAlign: WrapAlignment.center)) // Text(bio!, style: const TextStyle(fontSize: 18)), ], ), ), diff --git a/lib/views/tl_match_view.dart b/lib/views/tl_match_view.dart index f61d586..512241a 100644 --- a/lib/views/tl_match_view.dart +++ b/lib/views/tl_match_view.dart @@ -268,7 +268,7 @@ class TlMatchResultState extends State { ), Wrap( direction: Axis.horizontal, - alignment: WrapAlignment.spaceAround, + alignment: WrapAlignment.center, spacing: 25, crossAxisAlignment: WrapCrossAlignment.start, clipBehavior: Clip.hardEdge, diff --git a/lib/widgets/tl_thingy.dart b/lib/widgets/tl_thingy.dart index 8367812..55f6d59 100644 --- a/lib/widgets/tl_thingy.dart +++ b/lib/widgets/tl_thingy.dart @@ -13,7 +13,8 @@ class TLThingy extends StatelessWidget { final String userID; final TetraLeagueAlpha? oldTl; final bool showTitle; - const TLThingy({Key? key, required this.tl, required this.userID, this.oldTl, this.showTitle = true}) : super(key: key); + final double? topTR; + const TLThingy({Key? key, required this.tl, required this.userID, this.oldTl, this.showTitle = true, this.topTR}) : super(key: key); @override Widget build(BuildContext context) { @@ -55,7 +56,7 @@ class TLThingy extends StatelessWidget { ), ), Text( - "${t.top} ${f2.format(tl.percentile * 100)}% (${tl.percentileRank.toUpperCase()})${tl.bestRank != "z" ? " • ${t.topRank}: ${tl.bestRank.toUpperCase()}" : ""} • Glicko: ${f2.format(tl.glicko!)}±${f2.format(tl.rd!)}${tl.decaying ? ' • ${t.decaying}' : ''}", + "${t.top} ${f2.format(tl.percentile * 100)}% (${tl.percentileRank.toUpperCase()})${tl.bestRank != "z" ? " • ${t.topRank}: ${tl.bestRank.toUpperCase()}" : ""}${topTR != null ? " (${f2.format(topTR)} TR)" : ""} • Glicko: ${f2.format(tl.glicko!)}±${f2.format(tl.rd!)}${tl.decaying ? ' • ${t.decaying}' : ''}", textAlign: TextAlign.center, ), ], @@ -346,7 +347,7 @@ class TLThingy extends StatelessWidget { if (tl.nerdStats != null) Wrap( direction: Axis.horizontal, - alignment: WrapAlignment.spaceAround, + alignment: WrapAlignment.center, spacing: 25, crossAxisAlignment: WrapCrossAlignment.start, clipBehavior: Clip.hardEdge, diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 9f99dda..7b27c01 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,17 +7,25 @@ #include "generated_plugin_registrant.h" #include +#include #include #include +#include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); file_selector_plugin_register_with_registrar(file_selector_linux_registrar); + g_autoptr(FlPluginRegistrar) screen_retriever_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); + screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin"); sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); + g_autoptr(FlPluginRegistrar) window_manager_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); + window_manager_plugin_register_with_registrar(window_manager_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 3ff88a3..e34761b 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,8 +4,10 @@ list(APPEND FLUTTER_PLUGIN_LIST file_selector_linux + screen_retriever sqlite3_flutter_libs url_launcher_linux + window_manager ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 2416f81..98fd234 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,17 +8,21 @@ import Foundation import file_selector_macos import package_info_plus import path_provider_foundation +import screen_retriever import shared_preferences_foundation import sqflite import sqlite3_flutter_libs import url_launcher_macos +import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index f6bd23c..0e451f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -291,6 +291,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "8afc9a6aa6d8e8063523192ba837149dbf3d377a37c0b0fc579149a1fbd4a619" + url: "https://pub.dev" + source: hosted + version: "0.6.18" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -421,6 +429,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + markdown: + dependency: transitive + description: + name: markdown + sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd + url: "https://pub.dev" + source: hosted + version: "7.1.1" matcher: dependency: transitive description: @@ -605,6 +621,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + screen_retriever: + dependency: transitive + description: + name: screen_retriever + sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" + url: "https://pub.dev" + source: hosted + version: "0.1.9" shared_preferences: dependency: "direct main" description: @@ -1018,6 +1042,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.8" + window_manager: + dependency: "direct main" + description: + name: window_manager + sha256: dcc865277f26a7dad263a47d0e405d77e21f12cb71f30333a52710a408690bd7 + url: "https://pub.dev" + source: hosted + version: "0.3.7" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index afd6412..c3ed7fe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,6 +39,8 @@ dependencies: csv: ^5.0.2 url_launcher: ^6.1.12 flutter_svg: any + window_manager: ^0.3.7 + flutter_markdown: ^0.6.18 dev_dependencies: flutter_test: @@ -82,6 +84,8 @@ flutter: - res/icons/kagari.png - res/icons/osk.svg - res/icons/tetrio-logo.svg + - res/icons/improvement-local.png + - res/icons/supporter-tag.png - res/tetrio_tl_alpha_ranks/x.png - res/tetrio_tl_alpha_ranks/u.png - res/tetrio_tl_alpha_ranks/ss.png @@ -127,6 +131,9 @@ flutter: - res/tetrio_badges/hnprism_1.png - res/tetrio_badges/hnprism_2.png - res/tetrio_badges/hnprism_3.png + - res/tetrio_badges/hnstratosphere50_1.png + - res/tetrio_badges/hnstratosphere50_2.png + - res/tetrio_badges/hnstratosphere50_3.png - res/tetrio_badges/ift_1.png - res/tetrio_badges/ift_2.png - res/tetrio_badges/ift_3.png @@ -140,6 +147,7 @@ flutter: - res/tetrio_badges/mmc_tabi_superlobby.png - res/tetrio_badges/mmc_tabi_superlobby2.png - res/tetrio_badges/mmc_tabi_superlobby3.png + - res/tetrio_badges/mmc_tabi_superlobby4.png - res/tetrio_badges/redgevo_1.png - res/tetrio_badges/redgevo_2.png - res/tetrio_badges/redgevo_3.png @@ -169,6 +177,9 @@ flutter: - res/tetrio_badges/thaitour_1.png - res/tetrio_badges/thaitour_2.png - res/tetrio_badges/thaitour_3.png + - res/tetrio_badges/ttsdpf_1.png + - res/tetrio_badges/ttsdpf_2.png + - res/tetrio_badges/ttsdpf_3.png - res/tetrio_badges/ttsdtc_1.png - res/tetrio_badges/ttsdtc_2.png - res/tetrio_badges/ttsdtc_3.png diff --git a/res/icons/improvement-local.png b/res/icons/improvement-local.png new file mode 100644 index 0000000..73c4662 Binary files /dev/null and b/res/icons/improvement-local.png differ diff --git a/res/icons/supporter-tag.png b/res/icons/supporter-tag.png new file mode 100644 index 0000000..9eea2ad Binary files /dev/null and b/res/icons/supporter-tag.png differ diff --git a/res/tetrio_badges/hnstratosphere50_1.png b/res/tetrio_badges/hnstratosphere50_1.png new file mode 100644 index 0000000..21b0ea7 Binary files /dev/null and b/res/tetrio_badges/hnstratosphere50_1.png differ diff --git a/res/tetrio_badges/hnstratosphere50_2.png b/res/tetrio_badges/hnstratosphere50_2.png new file mode 100644 index 0000000..8928550 Binary files /dev/null and b/res/tetrio_badges/hnstratosphere50_2.png differ diff --git a/res/tetrio_badges/hnstratosphere50_3.png b/res/tetrio_badges/hnstratosphere50_3.png new file mode 100644 index 0000000..d251ebf Binary files /dev/null and b/res/tetrio_badges/hnstratosphere50_3.png differ diff --git a/res/tetrio_badges/mmc_tabi_superlobby4.png b/res/tetrio_badges/mmc_tabi_superlobby4.png new file mode 100644 index 0000000..08d6401 Binary files /dev/null and b/res/tetrio_badges/mmc_tabi_superlobby4.png differ diff --git a/res/tetrio_badges/ttsdpf_1.png b/res/tetrio_badges/ttsdpf_1.png new file mode 100644 index 0000000..4749f2e Binary files /dev/null and b/res/tetrio_badges/ttsdpf_1.png differ diff --git a/res/tetrio_badges/ttsdpf_2.png b/res/tetrio_badges/ttsdpf_2.png new file mode 100644 index 0000000..136d014 Binary files /dev/null and b/res/tetrio_badges/ttsdpf_2.png differ diff --git a/res/tetrio_badges/ttsdpf_3.png b/res/tetrio_badges/ttsdpf_3.png new file mode 100644 index 0000000..ba2c977 Binary files /dev/null and b/res/tetrio_badges/ttsdpf_3.png differ diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index c8dbaef..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:tetra_stats/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - // await tester.pumpWidget(const MyApp()); - // - // // Verify that our counter starts at 0. - // expect(find.text('0'), findsOneWidget); - // expect(find.text('1'), findsNothing); - // - // // Tap the '+' icon and trigger a frame. - // await tester.tap(find.byIcon(Icons.add)); - // await tester.pump(); - // - // // Verify that our counter has incremented. - // expect(find.text('0'), findsNothing); - // expect(find.text('1'), findsOneWidget); - }); -} diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index b874386..c2ea172 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,14 +7,20 @@ #include "generated_plugin_registrant.h" #include +#include #include #include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); + ScreenRetrieverPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); Sqlite3FlutterLibsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); + WindowManagerPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("WindowManagerPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 1ef42a8..6dbf6fa 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,8 +4,10 @@ list(APPEND FLUTTER_PLUGIN_LIST file_selector_windows + screen_retriever sqlite3_flutter_libs url_launcher_windows + window_manager ) list(APPEND FLUTTER_FFI_PLUGIN_LIST