Peak TR + Markdown in bio + icons in news

Also small redesign, window title now changes,
illegally downloaded badges and other small things
This commit is contained in:
dan63047 2023-10-08 20:20:42 +03:00
parent 7060eb6e43
commit c6d1e0787a
25 changed files with 213 additions and 80 deletions

View File

@ -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);
}

View File

@ -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){

View File

@ -54,6 +54,7 @@ class TetrioService extends DB {
final Map<String, Map<String, dynamic>> _recordsCache = {};
final Map<String, TetrioPlayersLeaderboard> _leaderboardsCache = {};
final Map<String, List<News>> _newsCache = {};
final Map<String, Map<String, double?>> _topTRcache = {};
final Map<String, TetraLeagueAlphaStream> _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<double?> 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<List<TetrioPlayer>> fetchAndsaveTLHistory(String id) async {
Uri url;
if (kIsWeb) {
@ -238,7 +291,6 @@ class TetrioService extends DB {
}
}
// TODO: Future<List<News>> getNews(String userID) async
Future<List<News>> fetchNews(String userID) async{
try{
var cached = _newsCache.entries.firstWhere((element) => element.value[0].stream == "user_$userID");

View File

@ -42,7 +42,7 @@ class CalcState extends State<CalcView> {
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<CalcView> {
_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,

View File

@ -642,7 +642,7 @@ class CompareState extends State<CompareView> {
),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.spaceAround,
alignment: WrapAlignment.center,
spacing: 25,
crossAxisAlignment: WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge,

View File

@ -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<List> me = Future.delayed(const Duration(seconds: 60), () => [null, null, null, null, null, null]);
String _searchFor = "6098518e3d5155e6ec429cdc";
@ -136,10 +138,25 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
}
_searchFor = me.userId;
setState((){_titleNickname = me.username;});
List<dynamic> requests = await Future.wait([teto.getTLStream(_searchFor), teto.fetchRecords(_searchFor), teto.fetchNews(_searchFor)]);
TetraLeagueAlphaStream tlStream = requests[0] as TetraLeagueAlphaStream;
Map<String, dynamic> records = requests[1] as Map<String, dynamic>;
List<News> news = requests[2] as List<News>;
await windowManager.setTitle('Tetra Stats: $_titleNickname'); //TODO: Change window title on every view
late List<dynamic> requests;
late TetraLeagueAlphaStream tlStream;
late Map<String, dynamic> records;
late List<News> 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<String, dynamic>;
news = requests[2] as List<News>;
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<String, dynamic>;
news = requests[2] as List<News>;
topTR = null;
}
List<TetraLeagueAlphaRecord> tlMatches = [];
bool isTracking = await teto.isPlayerTracking(me.userId);
List<TetrioPlayer> states = [];
@ -191,7 +208,7 @@ class _MainState extends State<MainView> 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<MainView> 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<NavDrawer> {
final allPlayers = (snapshot.data != null)
? snapshot.data as Map<String, List<TetrioPlayer>>
: <String, List<TetrioPlayer>>{};
List<String> keys = allPlayers.keys.toList().reversed.toList(); // this is so dumb
List<String> keys = allPlayers.keys.toList();
return NestedScrollView(
headerSliverBuilder: (context, value) {
return [
@ -521,9 +526,9 @@ class _NavDrawerState extends State<NavDrawer> {
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)),
],
),
),

View File

@ -268,7 +268,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
),
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.spaceAround,
alignment: WrapAlignment.center,
spacing: 25,
crossAxisAlignment: WrapCrossAlignment.start,
clipBehavior: Clip.hardEdge,

View File

@ -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,

View File

@ -7,17 +7,25 @@
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h>
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);
}

View File

@ -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

View File

@ -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"))
}

View File

@ -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:

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
res/icons/supporter-tag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -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);
});
}

View File

@ -7,14 +7,20 @@
#include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
#include <window_manager/window_manager_plugin.h>
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"));
}

View File

@ -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