From 56ab75730eb591a3ebfec52d60946515cd771fa7 Mon Sep 17 00:00:00 2001 From: Anh Date: Fri, 15 Nov 2024 13:39:18 +0700 Subject: [PATCH] Show missing and existed resources --- flutter/lib/l10n/app_en.arb | 1 + flutter/lib/resources/resource_manager.dart | 17 ++- flutter/lib/resources/validation_helper.dart | 9 +- flutter/lib/ui/home/app_drawer.dart | 2 +- flutter/lib/ui/settings/resources_screen.dart | 118 ++++++++++++++++-- 5 files changed, 127 insertions(+), 20 deletions(-) diff --git a/flutter/lib/l10n/app_en.arb b/flutter/lib/l10n/app_en.arb index e614d8bd8..3f3c07eb6 100644 --- a/flutter/lib/l10n/app_en.arb +++ b/flutter/lib/l10n/app_en.arb @@ -119,6 +119,7 @@ "resourceDownload": "Download", "resourceClear": "Clear", "resourceChecking": "Checking download status", + "resourceDownloading": "Downloading", "resourceErrorMessage": "Some resources failed to load.\nIf you didn't change config from default you can try clearing the cache.\nIf you use a custom configuration file ensure that it has correct structure or switch back to default config.", "resourceErrorSelectTaskFile": "Update task configuration", "resourceErrorCurrentConfig": "Current task config file: ", diff --git a/flutter/lib/resources/resource_manager.dart b/flutter/lib/resources/resource_manager.dart index 1957d0a06..f4d6d561f 100644 --- a/flutter/lib/resources/resource_manager.dart +++ b/flutter/lib/resources/resource_manager.dart @@ -167,8 +167,11 @@ class ResourceManager { resultManager = await ResultManager.create(applicationDirectory); } - Future> validateResourcesExist(List resources) async { + // Returns a map of { true: [existedResources], false: [missingResources] } + Future>> validateResourcesExist( + List resources) async { final missingResources = []; + final existedResources = []; for (var r in resources) { final resolvedPath = get(r.path); if (resolvedPath.isEmpty) { @@ -176,12 +179,18 @@ class ResourceManager { } else { final isResourceExist = await File(resolvedPath).exists() || await Directory(resolvedPath).exists(); - if (!isResourceExist) { - missingResources.add(resolvedPath); + if (isResourceExist) { + existedResources.add(r.path); + } else { + missingResources.add(r.path); } } } - return missingResources; + final result = { + false: missingResources, + true: existedResources, + }; + return result; } Future> validateResourcesChecksum( diff --git a/flutter/lib/resources/validation_helper.dart b/flutter/lib/resources/validation_helper.dart index a90322b8e..ce577e4cd 100644 --- a/flutter/lib/resources/validation_helper.dart +++ b/flutter/lib/resources/validation_helper.dart @@ -34,7 +34,8 @@ class ValidationHelper { modes: selectedRunModes, benchmarks: activeBenchmarks, ); - final missing = await resourceManager.validateResourcesExist(resources); + final result = await resourceManager.validateResourcesExist(resources); + final missing = result[false] ?? []; if (missing.isEmpty) return ''; return errorDescription + @@ -55,13 +56,13 @@ class ValidationHelper { .join(); } - Future validateResourcesExist( + Future>> validateResourcesExist( Benchmark benchmark, BenchmarkRunMode mode) async { final resources = benchmarkStore.listResources( modes: [mode], benchmarks: [benchmark], ); - final missing = await resourceManager.validateResourcesExist(resources); - return missing.isEmpty; + final result = await resourceManager.validateResourcesExist(resources); + return result; } } diff --git a/flutter/lib/ui/home/app_drawer.dart b/flutter/lib/ui/home/app_drawer.dart index 1b92305b5..b657daa53 100644 --- a/flutter/lib/ui/home/app_drawer.dart +++ b/flutter/lib/ui/home/app_drawer.dart @@ -9,8 +9,8 @@ import 'package:mlperfbench/ui/app_styles.dart'; import 'package:mlperfbench/ui/history/history_list_screen.dart'; import 'package:mlperfbench/ui/home/user_profile.dart'; import 'package:mlperfbench/ui/settings/about_screen.dart'; -import 'package:mlperfbench/ui/settings/settings_screen.dart'; import 'package:mlperfbench/ui/settings/resources_screen.dart'; +import 'package:mlperfbench/ui/settings/settings_screen.dart'; class AppDrawer extends StatelessWidget { const AppDrawer({super.key}); diff --git a/flutter/lib/ui/settings/resources_screen.dart b/flutter/lib/ui/settings/resources_screen.dart index e3a62218c..d3341faae 100644 --- a/flutter/lib/ui/settings/resources_screen.dart +++ b/flutter/lib/ui/settings/resources_screen.dart @@ -1,9 +1,9 @@ -import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; -import 'package:mlperfbench/benchmark/benchmark.dart'; +import 'package:bot_toast/bot_toast.dart'; import 'package:provider/provider.dart'; +import 'package:mlperfbench/benchmark/benchmark.dart'; import 'package:mlperfbench/benchmark/run_mode.dart'; import 'package:mlperfbench/benchmark/state.dart'; import 'package:mlperfbench/localizations/app_localizations.dart'; @@ -84,18 +84,43 @@ class _ResourcesScreen extends State { } Widget _downloadStatus(Benchmark benchmark, BenchmarkRunMode mode) { - return FutureBuilder( + return FutureBuilder>>( future: state.validator.validateResourcesExist(benchmark, mode), - builder: (BuildContext context, AsyncSnapshot snapshot) { + builder: (BuildContext context, + AsyncSnapshot>> snapshot) { if (snapshot.hasData && snapshot.data != null) { - final downloaded = snapshot.data!; + const double size = 18; const downloadedIcon = - Icon(Icons.check_circle, size: 16, color: Colors.green); + Icon(Icons.check_circle, size: size, color: Colors.green); const notDownloadedIcon = - Icon(Icons.check_circle_outline, size: 16, color: Colors.grey); + Icon(Icons.check_circle_outline, size: size, color: Colors.grey); + final result = snapshot.data!; + final missing = result[false] ?? []; + final existed = result[true] ?? []; + final downloaded = missing.isEmpty; return Row( children: [ - downloaded ? downloadedIcon : notDownloadedIcon, + SizedBox( + height: size, + width: size, + child: IconButton( + padding: const EdgeInsets.all(0), + icon: downloaded ? downloadedIcon : notDownloadedIcon, + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return _ResourcesTable( + taskName: benchmark.info.taskName, + modeName: mode.readable, + missing: missing, + existed: existed, + ); + }, + ); + }, + ), + ), const SizedBox(width: 10), Text(mode.readable), ], @@ -117,13 +142,16 @@ class _ResourcesScreen extends State { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + l10n.resourceDownloading, + maxLines: 1, + style: const TextStyle(fontSize: 12), + ), Text( state.loadingPath, maxLines: 5, overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 12.0, - ), + style: const TextStyle(fontSize: 12), ), const SizedBox(height: 8), LinearProgressIndicator( @@ -184,3 +212,71 @@ class _ResourcesScreen extends State { ); } } + +class _ResourcesTable extends StatelessWidget { + final String taskName; + final String modeName; + final List missing; + final List existed; + + const _ResourcesTable({ + required this.taskName, + required this.modeName, + required this.missing, + required this.existed, + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Column( + children: [ + Text(taskName), + Text(modeName), + ], + ), + ), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + children: [ + const SizedBox(height: 20), + Table( + columnWidths: const { + 0: FixedColumnWidth(40), + 1: FlexColumnWidth(), + }, + border: TableBorder.all(color: Colors.grey), + defaultVerticalAlignment: TableCellVerticalAlignment.top, + children: [ + for (var path in missing) _row(path, false), + for (var path in existed) _row(path, true), + ], + ), + ], + ), + ), + ); + } + + TableRow _row(String path, bool existed) { + return TableRow( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + existed ? Icons.check_circle : Icons.check_circle_outline, + color: existed + ? Colors.green + : Colors.grey, // Grey check mark for missing + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(path), + ), + ], + ); + } +}