From 464903702737bb4e619e0e88b2fa1f79d6fc77f9 Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Tue, 2 Dec 2025 15:51:41 +0100 Subject: [PATCH] games screen --- .../games/presentation/games_add_screen.dart | 28 ++++++++++- .../games/presentation/games_screen.dart | 47 ++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/lib/features/games/presentation/games_add_screen.dart b/lib/features/games/presentation/games_add_screen.dart index 96067d0..6b8c64d 100644 --- a/lib/features/games/presentation/games_add_screen.dart +++ b/lib/features/games/presentation/games_add_screen.dart @@ -17,6 +17,26 @@ class _GamesAddScreenState extends ConsumerState { bool _loading = false; List> _results = const []; final Set _selected = {}; + Set _existing = {}; + + Future _loadExisting() async { + final backend = ref.read(backendApiProvider); + const pageSize = 500; + var offset = 0; + final ids = {}; + 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 _search() async { final q = _queryCtrl.text.trim(); @@ -27,9 +47,15 @@ class _GamesAddScreenState extends ConsumerState { _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) diff --git a/lib/features/games/presentation/games_screen.dart b/lib/features/games/presentation/games_screen.dart index 7e5a662..c7d0533 100644 --- a/lib/features/games/presentation/games_screen.dart +++ b/lib/features/games/presentation/games_screen.dart @@ -184,11 +184,47 @@ class GamesScreen extends ConsumerWidget { } } + Future _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 _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 }