feat: track newly installed VMs in prefs

This commit is contained in:
ivo 2025-05-13 20:07:09 +02:00
parent fd2ccebafe
commit 94dcd6c138
5 changed files with 58 additions and 40 deletions

View File

@ -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<String> fetchQuickemuVersion() async {
// Get the version of quickemu

View File

@ -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<String>) {
return prefs.getStringList(key) as T;
}
}

View File

@ -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<Downloader> {
class _DownloaderState extends State<Downloader> with PreferencesMixin {
final notificationsClient = Platform.isMacOS ? null : NotificationsClient();
final curlPattern = RegExp("( [0-9.]+%)");
late final Stream<double> _progressStream;
bool _downloadFinished = false;
var controller = StreamController<double>();
Process? _process;
String? _newestVmFolderName;
@override
void initState() {
@ -57,7 +58,7 @@ class _DownloaderState extends State<Downloader> {
}
}
Future<String?> findNewestFolder() async {
Future<void> addNewestVmToPrefs() async {
final dir = Directory.current;
final folders = await dir
.list()
@ -68,7 +69,18 @@ class _DownloaderState extends State<Downloader> {
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<String> newVmNames =
await getPreference<List<String>>(prefNewlyInstalledVms) ??
<String>[];
newVmNames.add(newestFolder);
savePreference(prefNewlyInstalledVms, newVmNames);
}
}
Stream<double> progressStream() {
@ -86,31 +98,29 @@ class _DownloaderState extends State<Downloader> {
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<Downloader> {
),
ManageMachinesAfterDownloadButton(
downloadFinished: _downloadFinished,
vmName: _newestVmFolderName ?? '',
),
CancelDismissButton(
onCancel: () {

View File

@ -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<Manager> createState() => _ManagerState();
@ -56,12 +54,14 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
'xterm',
];
Timer? refreshTimer;
List<String> newVmNames = <String>[];
@override
void initState() {
super.initState();
_getTerminalEmulator();
_detectSpice();
_setNewVmName();
getPreference<String>(prefWorkingDirectory).then((pref) {
setState(() {
if (pref == null) {
@ -83,6 +83,13 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
super.dispose();
}
Future<void> _setNewVmName() async {
newVmNames =
await getPreference<List<String>>(prefNewlyInstalledVms) ?? <String>[];
// Delete prefNewlyInstalledVms to only display once
savePreference(prefNewlyInstalledVms, <String>[]);
}
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<Manager> 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 = '';

View File

@ -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(),
),
);
},