Skip to content

commit 2dce7c1

abduznik edited this page May 23, 2026 · 1 revision

feat: add manual 'Force Full ROM Scan' button in settings

Commit: 2dce7c17e77cc249bc92496ea48447f820f3b00f

Author: abduznik

Date: 2026-04-28

Why: Adds a new feature or capability to the application.

Files Changed

lib/core/romm/rom_scanner_service.dart             |  6 +++---
 lib/providers/downloaded_games_cache_provider.dart |  4 ++--
 lib/ui/screens/settings_screen.dart                | 23 ++++++++++++++++++++++
 3 files changed, 28 insertions(+), 5 deletions(-)
  • lib/core/romm/rom_scanner_service.dart
  • lib/providers/downloaded_games_cache_provider.dart
  • lib/ui/screens/settings_screen.dart

Diff

diff --git a/lib/core/romm/rom_scanner_service.dart b/lib/core/romm/rom_scanner_service.dart
index 2f295c0..bc15360 100644
--- a/lib/core/romm/rom_scanner_service.dart
+++ b/lib/core/romm/rom_scanner_service.dart
@@ -26,7 +26,7 @@ class RomScannerService {
   RomScannerService(this._rommService, this._mappingService, this._directoryService);
 
   /// Performs an incremental sync of the ROM directory.
-  Stream<RomSyncResult> sync(String romsRoot) async* {
+  Stream<RomSyncResult> sync(String romsRoot, {bool force = false}) async* {
     final mappings = _mappingService.getMappings();
     
     final rootDir = Directory(romsRoot);
@@ -53,9 +53,9 @@ class RomScannerService {
       }
     }
 
-    bool forceFullScan = mappings.length < 10 && platformDirs.length > 5;
+    bool forceFullScan = force || (mappings.length < 10 && platformDirs.length > 5);
 
-    if (dirtyDirs.isEmpty && !forceFullScan) {
+    if (!force && dirtyDirs.isEmpty && !forceFullScan) {
       debugPrint('[RomScanner] No platform directories changed. Skipping scan.');
       return;
     }
diff --git a/lib/providers/downloaded_games_cache_provider.dart b/lib/providers/downloaded_games_cache_provider.dart
index 8a2dc35..32dbf1d 100644
--- a/lib/providers/downloaded_games_cache_provider.dart
+++ b/lib/providers/downloaded_games_cache_provider.dart
@@ -88,7 +88,7 @@ class DownloadedGamesCache extends StateNotifier<Map<String, bool>> {
   }
 
   /// Runs the high-performance incremental sync.
-  Future<void> startIncrementalSync() async {
+  Future<void> startIncrementalSync({bool force = false}) async {
     if (_isSyncing) return;
     
     final scanner = _ref.read(romScannerServiceProvider);
@@ -111,7 +111,7 @@ class DownloadedGamesCache extends StateNotifier<Map<String, bool>> {
       final Map<String, bool> sessionMatches = {};
       
       int count = 0;
-      await for (final result in scanner.sync(romsRoot)) {
+      await for (final result in scanner.sync(romsRoot, force: force)) {
         // Handle removals IMMEDIATELY
         if (result.isRemoved && result.romId != null) {
           final newState = Map<String, bool>.from(state);
diff --git a/lib/ui/screens/settings_screen.dart b/lib/ui/screens/settings_screen.dart
index 80a86aa..3947de2 100644
--- a/lib/ui/screens/settings_screen.dart
+++ b/lib/ui/screens/settings_screen.dart
@@ -9,6 +9,7 @@ import '../../core/storage/system_utils.dart';
 import '../../providers/romm_provider.dart';
 import '../../providers/library_provider.dart';
 import '../../providers/shared_prefs_provider.dart';
+import '../../providers/downloaded_games_cache_provider.dart';
 import '../../core/romm/romm_service.dart';
 import '../../core/romm/romm_models.dart';
 import 'settings_emulators_section.dart';
@@ -342,6 +343,28 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
         icon: const Icon(Icons.folder_open),
         label: const Text('Open App Data Directory'),
       ),
+      const SizedBox(height: 16),
+      const Divider(color: Colors.white10),
+      const SizedBox(height: 8),
+      const Text('Troubleshooting', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
+      const SizedBox(height: 8),
+      const Text('If games are missing from your offline library, try a full scan.', style: TextStyle(color: Colors.white54, fontSize: 13)),
+      const SizedBox(height: 12),
+      Consumer(builder: (context, ref, _) {
+        final isScanning = ref.watch(isScanningProvider);
+        return OutlinedButton.icon(
+          onPressed: isScanning ? null : () async {
+            await ref.read(downloadedGamesCacheProvider.notifier).startIncrementalSync(force: true);
+            if (context.mounted) {
+              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Full ROM scan complete.')));
+            }
+          },
+          icon: isScanning 
+            ? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2))
+            : const Icon(Icons.sync),
+          label: Text(isScanning ? 'Scanning...' : 'Force Full ROM Scan'),
+        );
+      }),
     ]);
   }
 

Clone this wiki locally