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 {
|
||||
await udb.open();
|
||||
await open();
|
||||
} on DatabaseAlreadyOpen {
|
||||
// empty
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
import 'dart:developer' as developer;
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:async';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
// import 'package:sqflite/sqflite.dart';
|
||||
// import 'package:path_provider/path_provider.dart' show MissingPlatformDirectoryException, getApplicationDocumentsDirectory;
|
||||
// import 'package:path/path.dart' show join;
|
||||
|
@ -22,22 +24,34 @@ const String createTetrioUsersTable = '''
|
|||
PRIMARY KEY("id")
|
||||
);''';
|
||||
|
||||
class TetrioService {
|
||||
class TetrioService extends DB {
|
||||
Map<String, List<TetrioPlayer>> _players = {};
|
||||
final _tetrioStreamController = StreamController<Map<String, List<TetrioPlayer>>>.broadcast();
|
||||
|
||||
TetrioService(DB udb) {
|
||||
_cachePlayers(udb);
|
||||
static final TetrioService _shared = TetrioService._sharedInstance();
|
||||
factory TetrioService() => _shared;
|
||||
late final StreamController<Map<String, List<TetrioPlayer>>> _tetrioStreamController;
|
||||
TetrioService._sharedInstance() {
|
||||
_tetrioStreamController = StreamController<Map<String, List<TetrioPlayer>>>.broadcast(onListen: () {
|
||||
_tetrioStreamController.sink.add(_players);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _cachePlayers(DB udb) async {
|
||||
final allPlayers = await getAllPlayers(udb: udb);
|
||||
@override
|
||||
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; // ???
|
||||
_tetrioStreamController.add(_players);
|
||||
developer.log("_cachePlayers: $_players", name: "services/tetrio_crud");
|
||||
}
|
||||
|
||||
Future<void> deletePlayer({required String id, required DB udb}) async {
|
||||
await ensureDbIsOpen();
|
||||
final db = udb.getDatabaseOrThrow();
|
||||
final deletedPlayer = await db.delete(tetrioUsersTable, where: '$idCol = ?', whereArgs: [id.toLowerCase()]);
|
||||
if (deletedPlayer != 1) {
|
||||
|
@ -58,9 +72,9 @@ class TetrioService {
|
|||
// }
|
||||
// }
|
||||
|
||||
Future<void> createPlayer({required TetrioPlayer tetrioPlayer, required DB udb}) async {
|
||||
_ensureDbIsOpen(udb);
|
||||
final db = udb.getDatabaseOrThrow();
|
||||
Future<void> createPlayer(TetrioPlayer tetrioPlayer) async {
|
||||
ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [tetrioPlayer.userId.toLowerCase()]);
|
||||
if (results.isNotEmpty) {
|
||||
throw TetrioPlayerAlreadyExist();
|
||||
|
@ -73,15 +87,15 @@ class TetrioService {
|
|||
_tetrioStreamController.add(_players);
|
||||
}
|
||||
|
||||
Future<void> storeState(TetrioPlayer tetrioPlayer, DB udb) async {
|
||||
_ensureDbIsOpen(udb);
|
||||
final db = udb.getDatabaseOrThrow();
|
||||
Future<void> storeState(TetrioPlayer tetrioPlayer) async {
|
||||
ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
late List<TetrioPlayer> states;
|
||||
try {
|
||||
states = await getPlayer(id: tetrioPlayer.userId, udb: udb);
|
||||
states = await getPlayer(tetrioPlayer.userId);
|
||||
} on TetrioPlayerNotExist {
|
||||
await createPlayer(tetrioPlayer: tetrioPlayer, udb: udb);
|
||||
states = await getPlayer(id: tetrioPlayer.userId, udb: udb);
|
||||
await createPlayer(tetrioPlayer);
|
||||
states = await getPlayer(tetrioPlayer.userId);
|
||||
}
|
||||
if (!_players[tetrioPlayer.userId]!.last.isSameState(tetrioPlayer)) states.add(tetrioPlayer);
|
||||
final Map<String, dynamic> statesJson = {};
|
||||
|
@ -94,9 +108,9 @@ class TetrioService {
|
|||
_tetrioStreamController.add(_players);
|
||||
}
|
||||
|
||||
Future<List<TetrioPlayer>> getPlayer({required String id, required DB udb}) async {
|
||||
_ensureDbIsOpen(udb);
|
||||
final db = udb.getDatabaseOrThrow();
|
||||
Future<List<TetrioPlayer>> getPlayer(String id) async {
|
||||
ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
List<TetrioPlayer> states = [];
|
||||
final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [id.toLowerCase()]);
|
||||
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()}');
|
||||
final response = await http.get(url);
|
||||
|
||||
|
@ -121,8 +135,8 @@ class TetrioService {
|
|||
TetrioPlayer player = TetrioPlayer.fromJson(
|
||||
jsonDecode(response.body)['data']['user'], DateTime.fromMillisecondsSinceEpoch(jsonDecode(response.body)['cache']['cached_at'], isUtc: true), true);
|
||||
if (addToDB) {
|
||||
_ensureDbIsOpen(udb);
|
||||
storeState(player, udb);
|
||||
await ensureDbIsOpen();
|
||||
storeState(player);
|
||||
}
|
||||
return player;
|
||||
} else {
|
||||
|
@ -135,17 +149,17 @@ class TetrioService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _ensureDbIsOpen(DB udb) async {
|
||||
try {
|
||||
await udb.open();
|
||||
} on DatabaseAlreadyOpen {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
// Future<void> _ensureDbIsOpen() async {
|
||||
// try {
|
||||
// await open();
|
||||
// } on DatabaseAlreadyOpen {
|
||||
// // empty
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<Iterable<Map<String, List<TetrioPlayer>>>> getAllPlayers({required DB udb}) async {
|
||||
await _ensureDbIsOpen(udb);
|
||||
final db = udb.getDatabaseOrThrow();
|
||||
Future<Iterable<Map<String, List<TetrioPlayer>>>> getAllPlayers() async {
|
||||
await ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
final players = await db.query(tetrioUsersTable);
|
||||
Map<String, List<TetrioPlayer>> data = {};
|
||||
//developer.log("getAllPlayers: $players", name: "services/tetrio_crud");
|
||||
|
|
|
@ -17,8 +17,7 @@ extension StringExtension on String {
|
|||
|
||||
String _searchFor = "dan63047";
|
||||
Future<TetrioPlayer>? me;
|
||||
DB db = DB();
|
||||
late final TetrioService teto;
|
||||
final TetrioService teto = TetrioService();
|
||||
late SharedPreferences prefs;
|
||||
const allowedHeightForPlayerIdInPixels = 40.0;
|
||||
const allowedHeightForPlayerBioInPixels = 30.0;
|
||||
|
@ -76,8 +75,8 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
db.open();
|
||||
teto = TetrioService(db);
|
||||
//teto = TetrioService();
|
||||
teto.open();
|
||||
_scrollController = ScrollController();
|
||||
_tabController = TabController(length: 4, vsync: this);
|
||||
_getPreferences().then((value) => changePlayer(prefs.getString("player") ?? "dan63047"));
|
||||
|
@ -89,7 +88,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
void dispose() {
|
||||
_tabController.dispose();
|
||||
_scrollController.dispose();
|
||||
db.close();
|
||||
//db.close();
|
||||
super.dispose();
|
||||
developer.log("Main view disposed", name: "main_view");
|
||||
}
|
||||
|
@ -102,7 +101,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
setState(() {
|
||||
_tabController.animateTo(0, duration: const Duration(milliseconds: 300));
|
||||
_searchFor = player;
|
||||
me = teto.fetchPlayer(player, db, false);
|
||||
me = teto.fetchPlayer(player, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -195,51 +194,62 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
future: me,
|
||||
builder: (context, snapshot) {
|
||||
developer.log("builder ($context): $snapshot", name: "main_view");
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
));
|
||||
}
|
||||
if (snapshot.hasData) {
|
||||
bool bigScreen = MediaQuery.of(context).size.width > 1024;
|
||||
return NestedScrollView(
|
||||
controller: _scrollController,
|
||||
headerSliverBuilder: (context, value) {
|
||||
return [
|
||||
SliverToBoxAdapter(child: _UserThingy(player: snapshot.data!)),
|
||||
SliverToBoxAdapter(
|
||||
child: TabBar(
|
||||
controller: _tabController,
|
||||
isScrollable: true,
|
||||
tabs: myTabs,
|
||||
onTap: (int tabId) {
|
||||
setState(() {
|
||||
developer.log("Tab changed to $tabId", name: "main_view");
|
||||
});
|
||||
},
|
||||
),
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.none:
|
||||
return Center(
|
||||
child: Text('none case of FutureBuilder',
|
||||
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||
case ConnectionState.waiting:
|
||||
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;
|
||||
if (snapshot.hasData) {
|
||||
return NestedScrollView(
|
||||
controller: _scrollController,
|
||||
headerSliverBuilder: (context, value) {
|
||||
return [
|
||||
SliverToBoxAdapter(child: _UserThingy(player: snapshot.data!)),
|
||||
SliverToBoxAdapter(
|
||||
child: TabBar(
|
||||
controller: _tabController,
|
||||
isScrollable: true,
|
||||
tabs: myTabs,
|
||||
onTap: (int tabId) {
|
||||
setState(() {
|
||||
developer.log("Tab changed to $tabId", name: "main_view");
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: TabBarView(
|
||||
controller: _tabController,
|
||||
children: [
|
||||
_TLThingy(tl: snapshot.data!.tlSeason1, userID: snapshot.data!.userId),
|
||||
_RecordThingy(record: (snapshot.data!.sprint.isNotEmpty) ? snapshot.data!.sprint[0] : null),
|
||||
_RecordThingy(record: (snapshot.data!.blitz.isNotEmpty) ? snapshot.data!.blitz[0] : null),
|
||||
_OtherThingy(zen: snapshot.data!.zen, bio: snapshot.data!.bio)
|
||||
],
|
||||
),
|
||||
];
|
||||
},
|
||||
body: TabBarView(
|
||||
controller: _tabController,
|
||||
children: [
|
||||
_TLThingy(tl: snapshot.data!.tlSeason1, userID: snapshot.data!.userId),
|
||||
_RecordThingy(record: (snapshot.data!.sprint.isNotEmpty) ? snapshot.data!.sprint[0] : null),
|
||||
_RecordThingy(record: (snapshot.data!.blitz.isNotEmpty) ? snapshot.data!.blitz[0] : null),
|
||||
_OtherThingy(zen: snapshot.data!.zen, bio: snapshot.data!.bio)
|
||||
],
|
||||
),
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text('${snapshot.error}', style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(
|
||||
child:
|
||||
Text('${snapshot.error}', style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return Center(
|
||||
child: Text('default case of FutureBuilder',
|
||||
style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center));
|
||||
}
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
));
|
||||
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();
|
||||
},
|
||||
),
|
||||
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: [
|
||||
Expanded(
|
||||
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,
|
||||
style: const TextStyle(
|
||||
fontFamily: "Eurostile Round",
|
||||
|
|
Loading…
Reference in New Issue