games screen
This commit is contained in:
@@ -17,6 +17,26 @@ class _GamesAddScreenState extends ConsumerState<GamesAddScreen> {
|
||||
bool _loading = false;
|
||||
List<Map<String, dynamic>> _results = const [];
|
||||
final Set<int> _selected = {};
|
||||
Set<int> _existing = {};
|
||||
|
||||
Future<void> _loadExisting() async {
|
||||
final backend = ref.read(backendApiProvider);
|
||||
const pageSize = 500;
|
||||
var offset = 0;
|
||||
final ids = <int>{};
|
||||
while (true) {
|
||||
final page = await backend.getGames(offset: offset, limit: pageSize);
|
||||
for (final g in page) {
|
||||
final v = (g['igdb_id'] as num?)?.toInt();
|
||||
if (v != null) ids.add(v);
|
||||
}
|
||||
if (page.length < pageSize) break;
|
||||
offset += pageSize;
|
||||
}
|
||||
setState(() {
|
||||
_existing = ids;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _search() async {
|
||||
final q = _queryCtrl.text.trim();
|
||||
@@ -27,9 +47,15 @@ class _GamesAddScreenState extends ConsumerState<GamesAddScreen> {
|
||||
_selected.clear();
|
||||
});
|
||||
try {
|
||||
await _loadExisting();
|
||||
final igdb = ref.read(igdbApiProvider);
|
||||
final items = await igdb.searchGames(q, limit: 30, lang: 'de');
|
||||
setState(() => _results = items);
|
||||
final filtered = items.where((g) {
|
||||
final id = (g['id'] as num?)?.toInt();
|
||||
if (id == null) return true;
|
||||
return !_existing.contains(id);
|
||||
}).toList();
|
||||
setState(() => _results = filtered);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context)
|
||||
|
||||
@@ -184,11 +184,47 @@ class GamesScreen extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setStatus(BuildContext context, WidgetRef ref, Game g, ItemStatus status) async {
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
try {
|
||||
await ref.read(backendApiProvider).setGameStatus(
|
||||
igdbId: g.igdbId,
|
||||
name: g.name,
|
||||
originalName: g.originalName,
|
||||
status: status.index,
|
||||
lang: 'de',
|
||||
title: g.localizedTitle ?? g.name,
|
||||
summary: g.summary,
|
||||
coverUrl: g.coverUrl,
|
||||
releaseYear: g.releaseYear,
|
||||
);
|
||||
// ignore: unused_result
|
||||
ref.invalidate(gamesStreamProvider);
|
||||
// ignore: unused_result
|
||||
ref.invalidate(gamesProvider);
|
||||
messenger.showSnackBar(SnackBar(content: Text('Status auf ${status.name} gesetzt')));
|
||||
} catch (e) {
|
||||
messenger.showSnackBar(SnackBar(content: Text('Status-Update fehlgeschlagen: $e')));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showContextMenu(BuildContext context, WidgetRef ref, Game g, Offset pos) async {
|
||||
final selected = await showMenu<_GameAction>(
|
||||
context: context,
|
||||
position: RelativeRect.fromLTRB(pos.dx, pos.dy, pos.dx, pos.dy),
|
||||
items: const [
|
||||
PopupMenuItem(
|
||||
value: _GameAction.setInit,
|
||||
child: Text('Set to Init'),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _GameAction.setProgress,
|
||||
child: Text('Set to Progress'),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _GameAction.setDone,
|
||||
child: Text('Set to Done'),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _GameAction.update,
|
||||
child: Text('Update'),
|
||||
@@ -201,6 +237,15 @@ class GamesScreen extends ConsumerWidget {
|
||||
);
|
||||
if (selected == null) return;
|
||||
switch (selected) {
|
||||
case _GameAction.setInit:
|
||||
await _setStatus(context, ref, g, ItemStatus.Init);
|
||||
break;
|
||||
case _GameAction.setProgress:
|
||||
await _setStatus(context, ref, g, ItemStatus.Progress);
|
||||
break;
|
||||
case _GameAction.setDone:
|
||||
await _setStatus(context, ref, g, ItemStatus.Done);
|
||||
break;
|
||||
case _GameAction.update:
|
||||
await _updateGame(context, ref, g);
|
||||
break;
|
||||
@@ -211,4 +256,4 @@ class GamesScreen extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
enum _GameAction { update, delete }
|
||||
enum _GameAction { setInit, setProgress, setDone, update, delete }
|
||||
|
||||
Reference in New Issue
Block a user