From 94dcd6c1382e31fdf113a4fac0313927d17edc1e Mon Sep 17 00:00:00 2001 From: ivo Date: Tue, 13 May 2025 20:07:09 +0200 Subject: [PATCH] feat: track newly installed VMs in prefs --- lib/src/globals.dart | 1 + lib/src/mixins/preferences_mixin.dart | 2 +- lib/src/pages/downloader.dart | 69 +++++++++++-------- lib/src/pages/manager.dart | 20 ++++-- ...manage_machines_after_download_button.dart | 6 +- 5 files changed, 58 insertions(+), 40 deletions(-) diff --git a/lib/src/globals.dart b/lib/src/globals.dart index b20f170..48558d0 100644 --- a/lib/src/globals.dart +++ b/lib/src/globals.dart @@ -4,6 +4,7 @@ var gIsSnap = Platform.environment['SNAP']?.isNotEmpty ?? false; const String prefWorkingDirectory = 'workingDirectory'; const String prefThemeMode = 'themeMode'; const String prefCurrentLocale = 'currentLocale'; +const String prefNewlyInstalledVms = 'newlyInstalledVms'; Future fetchQuickemuVersion() async { // Get the version of quickemu diff --git a/lib/src/mixins/preferences_mixin.dart b/lib/src/mixins/preferences_mixin.dart index a43d9ae..2083b3e 100644 --- a/lib/src/mixins/preferences_mixin.dart +++ b/lib/src/mixins/preferences_mixin.dart @@ -27,7 +27,7 @@ mixin PreferencesMixin { return prefs.getInt(key) as T; } else if (T == String) { return prefs.getString(key) as T; - } else if (T == List) { + } else if (T == List) { return prefs.getStringList(key) as T; } } diff --git a/lib/src/pages/downloader.dart b/lib/src/pages/downloader.dart index d5a43df..2e3c6d2 100644 --- a/lib/src/pages/downloader.dart +++ b/lib/src/pages/downloader.dart @@ -5,8 +5,10 @@ import 'dart:io'; import 'package:desktop_notifications/desktop_notifications.dart'; import 'package:flutter/material.dart'; import 'package:gettext_i18n/gettext_i18n.dart'; -import 'package:quickgui/src/widgets/downloader/run_image_button.dart'; +import 'package:quickgui/src/globals.dart'; +import 'package:quickgui/src/widgets/downloader/manage_machines_after_download_button.dart'; import 'package:path/path.dart' as p; +import 'package:quickgui/src/mixins/preferences_mixin.dart'; import '../model/operating_system.dart'; import '../model/option.dart'; @@ -31,14 +33,13 @@ class Downloader extends StatefulWidget { _DownloaderState createState() => _DownloaderState(); } -class _DownloaderState extends State { +class _DownloaderState extends State with PreferencesMixin { final notificationsClient = Platform.isMacOS ? null : NotificationsClient(); final curlPattern = RegExp("( [0-9.]+%)"); late final Stream _progressStream; bool _downloadFinished = false; var controller = StreamController(); Process? _process; - String? _newestVmFolderName; @override void initState() { @@ -57,7 +58,7 @@ class _DownloaderState extends State { } } - Future findNewestFolder() async { + Future addNewestVmToPrefs() async { final dir = Directory.current; final folders = await dir .list() @@ -68,7 +69,18 @@ class _DownloaderState extends State { folders .sort((a, b) => b.statSync().modified.compareTo(a.statSync().modified)); - return folders.isNotEmpty ? p.basename(folders.first.path) : null; + // Update the prefNewlyInstalledVms with the newest folder + if (folders.isNotEmpty) { + String newestFolder = p.basename(folders.first.path); + + final List newVmNames = + await getPreference>(prefNewlyInstalledVms) ?? + []; + + newVmNames.add(newestFolder); + + savePreference(prefNewlyInstalledVms, newVmNames); + } } Stream progressStream() { @@ -86,31 +98,29 @@ class _DownloaderState extends State { process.exitCode.then((value) { bool _cancelled = value.isNegative; + controller.close(); - findNewestFolder().then( - (path) { - setState(() { - _downloadFinished = true; - _newestVmFolderName = path; - notificationsClient?.notify( - _cancelled - ? context.t('Download cancelled') - : context.t('Download complete'), - body: _cancelled - ? context.t( - 'Download of {0} has been canceled.', - args: [widget.operatingSystem.name], - ) - : context.t( - 'Download of {0} has completed.', - args: [widget.operatingSystem.name], - ), - appName: 'Quickgui', - expireTimeoutMs: 10000, /* 10 seconds */ - ); - }); - }, - ); + addNewestVmToPrefs(); + setState(() { + _downloadFinished = true; + + notificationsClient?.notify( + _cancelled + ? context.t('Download cancelled') + : context.t('Download complete'), + body: _cancelled + ? context.t( + 'Download of {0} has been canceled.', + args: [widget.operatingSystem.name], + ) + : context.t( + 'Download of {0} has completed.', + args: [widget.operatingSystem.name], + ), + appName: 'Quickgui', + expireTimeoutMs: 10000, /* 10 seconds */ + ); + }); }); setState(() { @@ -165,7 +175,6 @@ class _DownloaderState extends State { ), ManageMachinesAfterDownloadButton( downloadFinished: _downloadFinished, - vmName: _newestVmFolderName ?? '', ), CancelDismissButton( onCancel: () { diff --git a/lib/src/pages/manager.dart b/lib/src/pages/manager.dart index dc4e691..be74432 100644 --- a/lib/src/pages/manager.dart +++ b/lib/src/pages/manager.dart @@ -21,9 +21,7 @@ import '../model/vminfo.dart'; /// Displays a list of available VMs, running state and connection info, /// with buttons to start and stop VMs. class Manager extends StatefulWidget { - const Manager({super.key, this.newVmName}); - - final String? newVmName; + const Manager({super.key}); @override State createState() => _ManagerState(); @@ -56,12 +54,14 @@ class _ManagerState extends State with PreferencesMixin { 'xterm', ]; Timer? refreshTimer; + List newVmNames = []; @override void initState() { super.initState(); _getTerminalEmulator(); _detectSpice(); + _setNewVmName(); getPreference(prefWorkingDirectory).then((pref) { setState(() { if (pref == null) { @@ -83,6 +83,13 @@ class _ManagerState extends State with PreferencesMixin { super.dispose(); } + Future _setNewVmName() async { + newVmNames = + await getPreference>(prefNewlyInstalledVms) ?? []; + // Delete prefNewlyInstalledVms to only display once + savePreference(prefNewlyInstalledVms, []); + } + void _getTerminalEmulator() async { // Find out which terminal emulator we have set as the default. String result = whichSync('x-terminal-emulator') ?? ''; @@ -253,7 +260,12 @@ class _ManagerState extends State with PreferencesMixin { final bool active = _activeVms.containsKey(currentVm); final bool sshy = _sshVms.contains(currentVm); - final bool newVM = widget.newVmName == currentVm; + print('currentVm: $currentVm'); + print('newVmNames: $newVmNames'); + + final bool newVM = newVmNames.contains(currentVm); + + print('newVM $newVM'); VmInfo vmInfo = VmInfo(); String connectInfo = ''; diff --git a/lib/src/widgets/downloader/manage_machines_after_download_button.dart b/lib/src/widgets/downloader/manage_machines_after_download_button.dart index a339a69..07c89d4 100644 --- a/lib/src/widgets/downloader/manage_machines_after_download_button.dart +++ b/lib/src/widgets/downloader/manage_machines_after_download_button.dart @@ -5,12 +5,10 @@ import 'package:quickgui/src/pages/manager.dart'; class ManageMachinesAfterDownloadButton extends StatelessWidget { const ManageMachinesAfterDownloadButton({ required this.downloadFinished, - required this.vmName, super.key, }); final bool downloadFinished; - final String vmName; @override Widget build(BuildContext context) { @@ -30,9 +28,7 @@ class ManageMachinesAfterDownloadButton extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => Manager( - newVmName: vmName, - ), + builder: (context) => const Manager(), ), ); },