-
-
Notifications
You must be signed in to change notification settings - Fork 14
commit 36f73ef
abduznik edited this page May 23, 2026
·
1 revision
Commit: 36f73ef6cc022da860e62e600ee1e8c08bf35cbc
Author: abduznik
Date: 2026-04-29
Why: Fixes a bug or regression in the existing codebase.
lib/core/romm/rom_scanner_service.dart | 12 +--
lib/ui/screens/settings_screen.dart | 186 ++++++++++++++++++++++-----------
2 files changed, 133 insertions(+), 65 deletions(-)
lib/core/romm/rom_scanner_service.dartlib/ui/screens/settings_screen.dart
diff --git a/lib/core/romm/rom_scanner_service.dart b/lib/core/romm/rom_scanner_service.dart
index c9a0679..1142a81 100644
--- a/lib/core/romm/rom_scanner_service.dart
+++ b/lib/core/romm/rom_scanner_service.dart
@@ -55,7 +55,7 @@ class RomScannerService {
continue;
}
- debugPrint('[RomScanner] Syncing platform: $platformSlug (File-Centric)...');
+ debugPrint('[Scan] $platformSlug...');
// 1. Build local indices (ls)
final index = await FileSystemIndex.build(dir.path);
@@ -108,7 +108,7 @@ class RomScannerService {
continue;
}
- debugPrint('[Scanner] Discovery: $fileName');
+ debugPrint('[Scan] ? $fileName');
// Extract key search term (First 1-2 words, at least 3 chars)
final words = fileName.split(RegExp(r'[\s\.\-_\[\(]')).where((w) => w.length >= 3).toList();
@@ -119,13 +119,13 @@ class RomScannerService {
continue;
}
- debugPrint('[Scanner] Searching cloud for: "$searchTerm"...');
+ debugPrint('[Scan] Search: "$searchTerm"');
Game? matchedGame;
try {
final results = await _rommService.searchRoms(search: searchTerm, platformId: platformId);
- debugPrint('[Scanner] Cloud returned ${results.length} candidates for "$searchTerm"');
+ // debugPrint('[Scanner] Cloud returned ${results.length} candidates for "$searchTerm"');
for (final candidate in results) {
// VERIFICATION: Use the exact same robust logic the Detail Card uses
@@ -147,12 +147,12 @@ class RomScannerService {
}
if (matchedGame != null) {
- debugPrint('[Scanner] Locked: $fileName -> ${matchedGame.name} (ID: ${matchedGame.id})');
+ debugPrint('[Scan] Found: $fileName -> ${matchedGame.name}');
await _mappingService.updateMapping(entityPath, matchedGame.id);
matchedPathsInThisPlatform.add(entityPath);
yield RomSyncResult(entityPath, matchedGame.id, game: matchedGame);
} else {
- debugPrint('[Scanner] No cloud match for: $fileName');
+ // debugPrint('[Scanner] No cloud match for: $fileName');
}
// Small delay to avoid hammering the API
diff --git a/lib/ui/screens/settings_screen.dart b/lib/ui/screens/settings_screen.dart
index 53e3bac..691be90 100644
--- a/lib/ui/screens/settings_screen.dart
+++ b/lib/ui/screens/settings_screen.dart
@@ -378,65 +378,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
void _showLogsDialog(BuildContext context) {
showDialog(
context: context,
- builder: (context) => Dialog(
- child: Container(
- width: double.infinity,
- height: MediaQuery.of(context).size.height * 0.8,
- padding: const EdgeInsets.all(16),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- const Text('System Logs', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
- Row(
- children: [
- IconButton(
- icon: const Icon(Icons.delete_sweep),
- onPressed: () => LoggerService().clear(),
- tooltip: 'Clear Logs',
- ),
- IconButton(
- icon: const Icon(Icons.close),
- onPressed: () => Navigator.pop(context),
- ),
- ],
- ),
- ],
- ),
- const Divider(),
- Expanded(
- child: StreamBuilder<List<LogEntry>>(
- stream: LoggerService().logStream,
- initialData: LoggerService().logs,
- builder: (context, snapshot) {
- final logs = snapshot.data ?? [];
- return ListView.builder(
- reverse: true,
- itemCount: logs.length,
- itemBuilder: (context, index) {
- final log = logs[logs.length - 1 - index];
- return Padding(
- padding: const EdgeInsets.symmetric(vertical: 2),
- child: Text(
- log.toString(),
- style: const TextStyle(
- fontFamily: 'monospace',
- fontSize: 12,
- color: Colors.white70,
- ),
- ),
- );
- },
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
+ builder: (context) => const _LogsDialogContent(),
);
}
@@ -456,3 +398,129 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
Widget _buildLinuxSettingsSection(BuildContext context, WidgetRef ref, DirectoryService directoryService) => const SizedBox();
Widget _buildLegalSection(BuildContext context) => const SizedBox();
}
+
+class _LogsDialogContent extends StatefulWidget {
+ const _LogsDialogContent();
+
+ @override
+ State<_LogsDialogContent> createState() => _LogsDialogContentState();
+}
+
+class _LogsDialogContentState extends State<_LogsDialogContent> {
+ String _filter = 'ALL';
+ final ScrollController _scrollController = ScrollController();
+
+ @override
+ Widget build(BuildContext context) {
+ return Dialog(
+ child: Container(
+ width: double.infinity,
+ constraints: const BoxConstraints(maxWidth: 800),
+ height: MediaQuery.of(context).size.height * 0.8,
+ padding: const EdgeInsets.all(16),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const Text('System Logs', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
+ Row(
+ children: [
+ IconButton(
+ icon: const Icon(Icons.delete_sweep),
+ onPressed: () => LoggerService().clear(),
+ tooltip: 'Clear Logs',
+ ),
+ IconButton(
+ icon: const Icon(Icons.close),
+ onPressed: () => Navigator.pop(context),
+ ),
+ ],
+ ),
+ ],
+ ),
+ const SizedBox(height: 8),
+ SingleChildScrollView(
+ scrollDirection: Axis.horizontal,
+ child: Row(
+ children: [
+ _FilterChip(label: 'ALL', selected: _filter == 'ALL', onSelected: () => setState(() => _filter = 'ALL')),
+ const SizedBox(width: 8),
+ _FilterChip(label: 'SCANNER', selected: _filter == 'SCANNER', onSelected: () => setState(() => _filter = 'SCANNER')),
+ const SizedBox(width: 8),
+ _FilterChip(label: 'NETWORK', selected: _filter == 'NETWORK', onSelected: () => setState(() => _filter = 'NETWORK')),
+ const SizedBox(width: 8),
+ _FilterChip(label: 'ERROR', selected: _filter == 'ERROR', onSelected: () => setState(() => _filter = 'ERROR')),
+ ],
+ ),
+ ),
+ const Divider(),
+ Expanded(
+ child: StreamBuilder<List<LogEntry>>(
+ stream: LoggerService().logStream,
+ initialData: LoggerService().logs,
+ builder: (context, snapshot) {
+ final allLogs = snapshot.data ?? [];
+ final filteredLogs = allLogs.where((log) {
+ final msg = log.toString().toUpperCase();
+ if (_filter == 'ALL') return true;
+ if (_filter == 'SCANNER') return msg.contains('[SCAN]') || msg.contains('[ROM SCANNER]');
+ if (_filter == 'NETWORK') return msg.contains('[NETWORK]') || msg.contains('[ROMMSERVICE]');
+ if (_filter == 'ERROR') return msg.contains('ERROR') || msg.contains('FAILED');
+ return true;
+ }).toList();
+
+ final fullText = filteredLogs.map((e) => e.toString()).join('\n');
+
+ return Container(
+ width: double.infinity,
+ padding: const EdgeInsets.all(8),
+ decoration: BoxDecoration(
+ color: Colors.black26,
+ borderRadius: BorderRadius.circular(4),
+ ),
+ child: SelectionArea(
+ child: SingleChildScrollView(
+ controller: _scrollController,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: Text(
+ fullText,
+ style: const TextStyle(
+ fontFamily: 'monospace',
+ fontSize: 12,
+ color: Colors.white70,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class _FilterChip extends StatelessWidget {
+ final String label;
+ final bool selected;
+ final VoidCallback onSelected;
+
+ const _FilterChip({required this.label, required this.selected, required this.onSelected});
+
+ @override
+ Widget build(BuildContext context) {
+ return ChoiceChip(
+ label: Text(label, style: const TextStyle(fontSize: 11)),
+ selected: selected,
+ onSelected: (_) => onSelected(),
+ visualDensity: VisualDensity.compact,
+ );
+ }
+}