IT'S WORKING... Somehow
This commit is contained in:
parent
18f02a9c54
commit
ff04c27edb
|
@ -43,9 +43,9 @@ class DB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _ensureDbIsOpen(DB udb) async {
|
Future<void> ensureDbIsOpen() async {
|
||||||
try {
|
try {
|
||||||
await udb.open();
|
await open();
|
||||||
} on DatabaseAlreadyOpen {
|
} on DatabaseAlreadyOpen {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer' as developer;
|
import 'dart:developer' as developer;
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
// import 'package:sqflite/sqflite.dart';
|
// import 'package:sqflite/sqflite.dart';
|
||||||
// import 'package:path_provider/path_provider.dart' show MissingPlatformDirectoryException, getApplicationDocumentsDirectory;
|
// import 'package:path_provider/path_provider.dart' show MissingPlatformDirectoryException, getApplicationDocumentsDirectory;
|
||||||
// import 'package:path/path.dart' show join;
|
// import 'package:path/path.dart' show join;
|
||||||
|
@ -22,22 +24,34 @@ const String createTetrioUsersTable = '''
|
||||||
PRIMARY KEY("id")
|
PRIMARY KEY("id")
|
||||||
);''';
|
);''';
|
||||||
|
|
||||||
class TetrioService {
|
class TetrioService extends DB {
|
||||||
Map<String, List<TetrioPlayer>> _players = {};
|
Map<String, List<TetrioPlayer>> _players = {};
|
||||||
final _tetrioStreamController = StreamController<Map<String, List<TetrioPlayer>>>.broadcast();
|
static final TetrioService _shared = TetrioService._sharedInstance();
|
||||||
|
factory TetrioService() => _shared;
|
||||||
TetrioService(DB udb) {
|
late final StreamController<Map<String, List<TetrioPlayer>>> _tetrioStreamController;
|
||||||
_cachePlayers(udb);
|
TetrioService._sharedInstance() {
|
||||||
|
_tetrioStreamController = StreamController<Map<String, List<TetrioPlayer>>>.broadcast(onListen: () {
|
||||||
|
_tetrioStreamController.sink.add(_players);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _cachePlayers(DB udb) async {
|
@override
|
||||||
final allPlayers = await getAllPlayers(udb: udb);
|
Future<void> open() async {
|
||||||
|
await super.open();
|
||||||
|
await _cachePlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Map<String, List<TetrioPlayer>>> get allPlayers => _tetrioStreamController.stream;
|
||||||
|
|
||||||
|
Future<void> _cachePlayers() async {
|
||||||
|
final allPlayers = await getAllPlayers();
|
||||||
_players = allPlayers.toList().first; // ???
|
_players = allPlayers.toList().first; // ???
|
||||||
_tetrioStreamController.add(_players);
|
_tetrioStreamController.add(_players);
|
||||||
developer.log("_cachePlayers: $_players", name: "services/tetrio_crud");
|
developer.log("_cachePlayers: $_players", name: "services/tetrio_crud");
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deletePlayer({required String id, required DB udb}) async {
|
Future<void> deletePlayer({required String id, required DB udb}) async {
|
||||||
|
await ensureDbIsOpen();
|
||||||
final db = udb.getDatabaseOrThrow();
|
final db = udb.getDatabaseOrThrow();
|
||||||
final deletedPlayer = await db.delete(tetrioUsersTable, where: '$idCol = ?', whereArgs: [id.toLowerCase()]);
|
final deletedPlayer = await db.delete(tetrioUsersTable, where: '$idCol = ?', whereArgs: [id.toLowerCase()]);
|
||||||
if (deletedPlayer != 1) {
|
if (deletedPlayer != 1) {
|
||||||
|
@ -58,9 +72,9 @@ class TetrioService {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Future<void> createPlayer({required TetrioPlayer tetrioPlayer, required DB udb}) async {
|
Future<void> createPlayer(TetrioPlayer tetrioPlayer) async {
|
||||||
_ensureDbIsOpen(udb);
|
ensureDbIsOpen();
|
||||||
final db = udb.getDatabaseOrThrow();
|
final db = getDatabaseOrThrow();
|
||||||
final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [tetrioPlayer.userId.toLowerCase()]);
|
final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [tetrioPlayer.userId.toLowerCase()]);
|
||||||
if (results.isNotEmpty) {
|
if (results.isNotEmpty) {
|
||||||
throw TetrioPlayerAlreadyExist();
|
throw TetrioPlayerAlreadyExist();
|
||||||
|
@ -73,15 +87,15 @@ class TetrioService {
|
||||||
_tetrioStreamController.add(_players);
|
_tetrioStreamController.add(_players);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> storeState(TetrioPlayer tetrioPlayer, DB udb) async {
|
Future<void> storeState(TetrioPlayer tetrioPlayer) async {
|
||||||
_ensureDbIsOpen(udb);
|
ensureDbIsOpen();
|
||||||
final db = udb.getDatabaseOrThrow();
|
final db = getDatabaseOrThrow();
|
||||||
late List<TetrioPlayer> states;
|
late List<TetrioPlayer> states;
|
||||||
try {
|
try {
|
||||||
states = await getPlayer(id: tetrioPlayer.userId, udb: udb);
|
states = await getPlayer(tetrioPlayer.userId);
|
||||||
} on TetrioPlayerNotExist {
|
} on TetrioPlayerNotExist {
|
||||||
await createPlayer(tetrioPlayer: tetrioPlayer, udb: udb);
|
await createPlayer(tetrioPlayer);
|
||||||
states = await getPlayer(id: tetrioPlayer.userId, udb: udb);
|
states = await getPlayer(tetrioPlayer.userId);
|
||||||
}
|
}
|
||||||
if (!_players[tetrioPlayer.userId]!.last.isSameState(tetrioPlayer)) states.add(tetrioPlayer);
|
if (!_players[tetrioPlayer.userId]!.last.isSameState(tetrioPlayer)) states.add(tetrioPlayer);
|
||||||
final Map<String, dynamic> statesJson = {};
|
final Map<String, dynamic> statesJson = {};
|
||||||
|
@ -94,9 +108,9 @@ class TetrioService {
|
||||||
_tetrioStreamController.add(_players);
|
_tetrioStreamController.add(_players);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<TetrioPlayer>> getPlayer({required String id, required DB udb}) async {
|
Future<List<TetrioPlayer>> getPlayer(String id) async {
|
||||||
_ensureDbIsOpen(udb);
|
ensureDbIsOpen();
|
||||||
final db = udb.getDatabaseOrThrow();
|
final db = getDatabaseOrThrow();
|
||||||
List<TetrioPlayer> states = [];
|
List<TetrioPlayer> states = [];
|
||||||
final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [id.toLowerCase()]);
|
final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [id.toLowerCase()]);
|
||||||
if (results.isEmpty) {
|
if (results.isEmpty) {
|
||||||
|
@ -112,7 +126,7 @@ class TetrioService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<TetrioPlayer> fetchPlayer(String user, DB udb, bool addToDB) async {
|
Future<TetrioPlayer> fetchPlayer(String user, bool addToDB) async {
|
||||||
var url = Uri.https('ch.tetr.io', 'api/users/${user.toLowerCase().trim()}');
|
var url = Uri.https('ch.tetr.io', 'api/users/${user.toLowerCase().trim()}');
|
||||||
final response = await http.get(url);
|
final response = await http.get(url);
|
||||||
|
|
||||||
|
@ -121,8 +135,8 @@ class TetrioService {
|
||||||
TetrioPlayer player = TetrioPlayer.fromJson(
|
TetrioPlayer player = TetrioPlayer.fromJson(
|
||||||
jsonDecode(response.body)['data']['user'], DateTime.fromMillisecondsSinceEpoch(jsonDecode(response.body)['cache']['cached_at'], isUtc: true), true);
|
jsonDecode(response.body)['data']['user'], DateTime.fromMillisecondsSinceEpoch(jsonDecode(response.body)['cache']['cached_at'], isUtc: true), true);
|
||||||
if (addToDB) {
|
if (addToDB) {
|
||||||
_ensureDbIsOpen(udb);
|
await ensureDbIsOpen();
|
||||||
storeState(player, udb);
|
storeState(player);
|
||||||
}
|
}
|
||||||
return player;
|
return player;
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,17 +149,17 @@ class TetrioService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _ensureDbIsOpen(DB udb) async {
|
// Future<void> _ensureDbIsOpen() async {
|
||||||
try {
|
// try {
|
||||||
await udb.open();
|
// await open();
|
||||||
} on DatabaseAlreadyOpen {
|
// } on DatabaseAlreadyOpen {
|
||||||
// empty
|
// // empty
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
Future<Iterable<Map<String, List<TetrioPlayer>>>> getAllPlayers({required DB udb}) async {
|
Future<Iterable<Map<String, List<TetrioPlayer>>>> getAllPlayers() async {
|
||||||
await _ensureDbIsOpen(udb);
|
await ensureDbIsOpen();
|
||||||
final db = udb.getDatabaseOrThrow();
|
final db = getDatabaseOrThrow();
|
||||||
final players = await db.query(tetrioUsersTable);
|
final players = await db.query(tetrioUsersTable);
|
||||||
Map<String, List<TetrioPlayer>> data = {};
|
Map<String, List<TetrioPlayer>> data = {};
|
||||||
//developer.log("getAllPlayers: $players", name: "services/tetrio_crud");
|
//developer.log("getAllPlayers: $players", name: "services/tetrio_crud");
|
||||||
|
|
|
@ -17,8 +17,7 @@ extension StringExtension on String {
|
||||||
|
|
||||||
String _searchFor = "dan63047";
|
String _searchFor = "dan63047";
|
||||||
Future<TetrioPlayer>? me;
|
Future<TetrioPlayer>? me;
|
||||||
DB db = DB();
|
final TetrioService teto = TetrioService();
|
||||||
late final TetrioService teto;
|
|
||||||
late SharedPreferences prefs;
|
late SharedPreferences prefs;
|
||||||
const allowedHeightForPlayerIdInPixels = 40.0;
|
const allowedHeightForPlayerIdInPixels = 40.0;
|
||||||
const allowedHeightForPlayerBioInPixels = 30.0;
|
const allowedHeightForPlayerBioInPixels = 30.0;
|
||||||
|
@ -76,8 +75,8 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
db.open();
|
//teto = TetrioService();
|
||||||
teto = TetrioService(db);
|
teto.open();
|
||||||
_scrollController = ScrollController();
|
_scrollController = ScrollController();
|
||||||
_tabController = TabController(length: 4, vsync: this);
|
_tabController = TabController(length: 4, vsync: this);
|
||||||
_getPreferences().then((value) => changePlayer(prefs.getString("player") ?? "dan63047"));
|
_getPreferences().then((value) => changePlayer(prefs.getString("player") ?? "dan63047"));
|
||||||
|
@ -89,7 +88,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_tabController.dispose();
|
_tabController.dispose();
|
||||||
_scrollController.dispose();
|
_scrollController.dispose();
|
||||||
db.close();
|
//db.close();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
developer.log("Main view disposed", name: "main_view");
|
developer.log("Main view disposed", name: "main_view");
|
||||||
}
|
}
|
||||||
|
@ -102,7 +101,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tabController.animateTo(0, duration: const Duration(milliseconds: 300));
|
_tabController.animateTo(0, duration: const Duration(milliseconds: 300));
|
||||||
_searchFor = player;
|
_searchFor = player;
|
||||||
me = teto.fetchPlayer(player, db, false);
|
me = teto.fetchPlayer(player, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,14 +194,20 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
future: me,
|
future: me,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
developer.log("builder ($context): $snapshot", name: "main_view");
|
developer.log("builder ($context): $snapshot", name: "main_view");
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
switch (snapshot.connectionState) {
|
||||||
return const Center(
|
case ConnectionState.none:
|
||||||
child: CircularProgressIndicator(
|
return Center(
|
||||||
color: Colors.white,
|
child: Text('none case of FutureBuilder',
|
||||||
));
|
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||||
}
|
case ConnectionState.waiting:
|
||||||
if (snapshot.hasData) {
|
return const Center(child: CircularProgressIndicator(color: Colors.white));
|
||||||
|
case ConnectionState.active:
|
||||||
|
return Center(
|
||||||
|
child: Text('active case of FutureBuilder',
|
||||||
|
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||||
|
case ConnectionState.done:
|
||||||
bool bigScreen = MediaQuery.of(context).size.width > 1024;
|
bool bigScreen = MediaQuery.of(context).size.width > 1024;
|
||||||
|
if (snapshot.hasData) {
|
||||||
return NestedScrollView(
|
return NestedScrollView(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
headerSliverBuilder: (context, value) {
|
headerSliverBuilder: (context, value) {
|
||||||
|
@ -234,12 +239,17 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
);
|
);
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text('${snapshot.error}', style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
child:
|
||||||
|
Text('${snapshot.error}', style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||||
}
|
}
|
||||||
return const Center(
|
break;
|
||||||
child: CircularProgressIndicator(
|
default:
|
||||||
color: Colors.white,
|
return Center(
|
||||||
));
|
child: Text('default case of FutureBuilder',
|
||||||
|
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||||
|
}
|
||||||
|
return Center(
|
||||||
|
child: Text('end of FutureBuilder', style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -271,6 +281,20 @@ class NavDrawer extends StatelessWidget {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
StreamBuilder(
|
||||||
|
stream: teto.allPlayers,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
switch (snapshot.connectionState) {
|
||||||
|
case ConnectionState.none:
|
||||||
|
return Center(child: Text('none case of StreamBuilder'));
|
||||||
|
case ConnectionState.waiting:
|
||||||
|
case ConnectionState.active:
|
||||||
|
return Center(child: Text('${snapshot.data}'));
|
||||||
|
case ConnectionState.done:
|
||||||
|
return Center(child: Text('done case of StreamBuilder'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -452,7 +476,7 @@ class _UserThingy extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"${player.country != null ? "${player.country?.toUpperCase()} • " : ""}${player.role.capitalize()} account ${player.registrationTime == null ? "that was from very beginning" : 'created ${player.registrationTime}'} • ${player.supporterTier == 0 ? "Not a supporter" : "Supporter tier ${player.supporterTier}"}",
|
"${player.country != null ? "${player.country?.toUpperCase()} • " : ""}${player.role.capitalize()} account ${player.registrationTime == null ? "that was from very beginning" : 'created ${player.registrationTime}'}${player.botmaster != null ? " by ${player.botmaster}" : ""} • ${player.supporterTier == 0 ? "Not a supporter" : "Supporter tier ${player.supporterTier}"}",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontFamily: "Eurostile Round",
|
fontFamily: "Eurostile Round",
|
||||||
|
|
Loading…
Reference in New Issue