Source code formated at 80 columns.
This commit is contained in:
parent
56cadacd4a
commit
0837bf9d80
|
@ -77,7 +77,9 @@ class _DownloaderState extends State<Downloader> {
|
||||||
} else if (widget.option!.downloader == 'zsync') {
|
} else if (widget.option!.downloader == 'zsync') {
|
||||||
controller.add(-1);
|
controller.add(-1);
|
||||||
} else if (widget.option!.downloader == 'macrecovery') {
|
} else if (widget.option!.downloader == 'macrecovery') {
|
||||||
process.stdout.transform(utf8.decoder).forEach(parseMacRecoveryProgress);
|
process.stdout
|
||||||
|
.transform(utf8.decoder)
|
||||||
|
.forEach(parseMacRecoveryProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exitCode.then((value) {
|
process.exitCode.then((value) {
|
||||||
|
@ -86,7 +88,9 @@ class _DownloaderState extends State<Downloader> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_downloadFinished = true;
|
_downloadFinished = true;
|
||||||
notificationsClient.notify(
|
notificationsClient.notify(
|
||||||
_cancelled ? context.t('Download cancelled') : context.t('Download complete'),
|
_cancelled
|
||||||
|
? context.t('Download cancelled')
|
||||||
|
: context.t('Download complete'),
|
||||||
body: _cancelled
|
body: _cancelled
|
||||||
? context.t(
|
? context.t(
|
||||||
'Download of {0} has completed.',
|
'Download of {0} has completed.',
|
||||||
|
@ -111,8 +115,12 @@ class _DownloaderState extends State<Downloader> {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
context.t('Downloading {0}',
|
context.t('Downloading {0}', args: [
|
||||||
args: ['${widget.operatingSystem.name} ${widget.version.version}' + (widget.option!.option.isNotEmpty ? ' (${widget.option!.option})' : '')]),
|
'${widget.operatingSystem.name} ${widget.version.version}' +
|
||||||
|
(widget.option!.option.isNotEmpty
|
||||||
|
? ' (${widget.option!.option})'
|
||||||
|
: '')
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
),
|
),
|
||||||
|
@ -122,7 +130,10 @@ class _DownloaderState extends State<Downloader> {
|
||||||
child: StreamBuilder(
|
child: StreamBuilder(
|
||||||
stream: _progressStream,
|
stream: _progressStream,
|
||||||
builder: (context, AsyncSnapshot<double> snapshot) {
|
builder: (context, AsyncSnapshot<double> snapshot) {
|
||||||
var data = !snapshot.hasData || widget.option!.downloader != 'wget' ? null : snapshot.data;
|
var data =
|
||||||
|
!snapshot.hasData || widget.option!.downloader != 'wget'
|
||||||
|
? null
|
||||||
|
: snapshot.data;
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
@ -137,7 +148,8 @@ class _DownloaderState extends State<Downloader> {
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 32),
|
padding: const EdgeInsets.only(top: 32),
|
||||||
child: Text(context.t('Target folder : {0}', args: [Directory.current.path])),
|
child: Text(context.t('Target folder : {0}',
|
||||||
|
args: [Directory.current.path])),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,7 +17,8 @@ class _MainPageState extends State<MainPage> {
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
setWindowTitle(context.t('Quickgui : a Flutter frontend for Quickget and Quickemu'));
|
setWindowTitle(
|
||||||
|
context.t('Quickgui : a Flutter frontend for Quickget and Quickemu'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -61,7 +61,8 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
}
|
}
|
||||||
Directory.current = pref;
|
Directory.current = pref;
|
||||||
});
|
});
|
||||||
Future.delayed(Duration.zero, () => _getVms(context)); // Reload VM list when we enter the page.
|
Future.delayed(Duration.zero,
|
||||||
|
() => _getVms(context)); // Reload VM list when we enter the page.
|
||||||
});
|
});
|
||||||
refreshTimer = Timer.periodic(const Duration(seconds: 5), (Timer t) {
|
refreshTimer = Timer.periodic(const Duration(seconds: 5), (Timer t) {
|
||||||
_getVms(context);
|
_getVms(context);
|
||||||
|
@ -78,7 +79,8 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
// Find out which terminal emulator we have set as the default.
|
// Find out which terminal emulator we have set as the default.
|
||||||
ProcessResult result = await Process.run('which', ['x-terminal-emulator']);
|
ProcessResult result = await Process.run('which', ['x-terminal-emulator']);
|
||||||
if (result.exitCode == 0) {
|
if (result.exitCode == 0) {
|
||||||
String terminalEmulator = await File(result.stdout.toString().trim()).resolveSymbolicLinks();
|
String terminalEmulator =
|
||||||
|
await File(result.stdout.toString().trim()).resolveSymbolicLinks();
|
||||||
terminalEmulator = path.basenameWithoutExtension(terminalEmulator);
|
terminalEmulator = path.basenameWithoutExtension(terminalEmulator);
|
||||||
if (_supportedTerminalEmulators.contains(terminalEmulator)) {
|
if (_supportedTerminalEmulators.contains(terminalEmulator)) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -130,7 +132,8 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
List<String> currentVms = [];
|
List<String> currentVms = [];
|
||||||
Map<String, VmInfo> activeVms = {};
|
Map<String, VmInfo> activeVms = {};
|
||||||
|
|
||||||
await for (var entity in Directory.current.list(recursive: false, followLinks: true)) {
|
await for (var entity
|
||||||
|
in Directory.current.list(recursive: false, followLinks: true)) {
|
||||||
if ((entity.path.endsWith('.conf')) && (_isValidConf(entity.path))) {
|
if ((entity.path.endsWith('.conf')) && (_isValidConf(entity.path))) {
|
||||||
String name = path.basenameWithoutExtension(entity.path);
|
String name = path.basenameWithoutExtension(entity.path);
|
||||||
currentVms.add(name);
|
currentVms.add(name);
|
||||||
|
@ -169,7 +172,9 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
|
|
||||||
Widget _buildVmList() {
|
Widget _buildVmList() {
|
||||||
List<Widget> _widgetList = [];
|
List<Widget> _widgetList = [];
|
||||||
final Color buttonColor = Theme.of(context).brightness == Brightness.dark ? Colors.white70 : Theme.of(context).colorScheme.primary;
|
final Color buttonColor = Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Colors.white70
|
||||||
|
: Theme.of(context).colorScheme.primary;
|
||||||
_widgetList.add(
|
_widgetList.add(
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
@ -181,7 +186,8 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
width: 8,
|
width: 8,
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(primary: Theme.of(context).canvasColor, onPrimary: buttonColor),
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Theme.of(context).canvasColor, onPrimary: buttonColor),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
String? result = await FilePicker.platform.getDirectoryPath();
|
String? result = await FilePicker.platform.getDirectoryPath();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -276,7 +282,9 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) => AlertDialog(
|
builder: (BuildContext context) => AlertDialog(
|
||||||
title: Text(context.t('Stop The Virtual Machine?')),
|
title: Text(context.t('Stop The Virtual Machine?')),
|
||||||
content: Text(context.t('You are about to terminate the virtual machine', args: [currentVm])),
|
content: Text(context.t(
|
||||||
|
'You are about to terminate the virtual machine',
|
||||||
|
args: [currentVm])),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, false),
|
onPressed: () => Navigator.pop(context, false),
|
||||||
|
@ -300,44 +308,49 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(Icons.delete,
|
||||||
Icons.delete,
|
color: active ? null : buttonColor,
|
||||||
color: active ? null : buttonColor,
|
semanticLabel: 'Delete'),
|
||||||
semanticLabel: 'Delete'
|
onPressed: active
|
||||||
),
|
? null
|
||||||
onPressed: active ? null : () {
|
: () {
|
||||||
showDialog<String?>(
|
showDialog<String?>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) => AlertDialog(
|
builder: (BuildContext context) => AlertDialog(
|
||||||
title: Text('Delete ' + currentVm),
|
title: Text('Delete ' + currentVm),
|
||||||
content: Text(
|
content: Text('You are about to delete ' +
|
||||||
'You are about to delete ' + currentVm + '. This cannot be undone. ' +
|
currentVm +
|
||||||
'Would you like to delete the disk image but keep the ' +
|
'. This cannot be undone. ' +
|
||||||
'configuration, or delete the whole VM?'
|
'Would you like to delete the disk image but keep the ' +
|
||||||
),
|
'configuration, or delete the whole VM?'),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text('Cancel'),
|
child: Text('Cancel'),
|
||||||
onPressed: () => Navigator.pop(context, 'cancel'),
|
onPressed: () =>
|
||||||
),
|
Navigator.pop(context, 'cancel'),
|
||||||
TextButton(
|
),
|
||||||
child: Text('Delete disk image'),
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'disk'),
|
child: Text('Delete disk image'),
|
||||||
),
|
onPressed: () => Navigator.pop(context, 'disk'),
|
||||||
TextButton(
|
),
|
||||||
child: Text('Delete whole VM'),
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'vm'),
|
child: Text('Delete whole VM'),
|
||||||
) // set up the AlertDialog
|
onPressed: () => Navigator.pop(context, 'vm'),
|
||||||
],
|
) // set up the AlertDialog
|
||||||
),
|
],
|
||||||
).then((result) async {
|
),
|
||||||
result = result ?? 'cancel';
|
).then((result) async {
|
||||||
if (result != 'cancel') {
|
result = result ?? 'cancel';
|
||||||
List<String> args = ['--vm', currentVm + '.conf', '--delete-' + result];
|
if (result != 'cancel') {
|
||||||
await Process.start('quickemu', args);
|
List<String> args = [
|
||||||
}
|
'--vm',
|
||||||
});
|
currentVm + '.conf',
|
||||||
},
|
'--delete-' + result
|
||||||
|
];
|
||||||
|
await Process.start('quickemu', args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
|
@ -351,7 +364,9 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
color: _spicy ? buttonColor : null,
|
color: _spicy ? buttonColor : null,
|
||||||
semanticLabel: 'Connect display with SPICE',
|
semanticLabel: 'Connect display with SPICE',
|
||||||
),
|
),
|
||||||
tooltip: _spicy ? 'Connect display with SPICE' : 'SPICE client not found',
|
tooltip: _spicy
|
||||||
|
? 'Connect display with SPICE'
|
||||||
|
: 'SPICE client not found',
|
||||||
onPressed: !_spicy
|
onPressed: !_spicy
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
|
@ -359,19 +374,25 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: SvgPicture.asset('assets/images/console.svg', semanticsLabel: 'Connect with SSH', color: sshy ? buttonColor : Colors.grey),
|
icon: SvgPicture.asset('assets/images/console.svg',
|
||||||
tooltip: sshy ? 'Connect with SSH' : 'SSH server not detected on guest',
|
semanticsLabel: 'Connect with SSH',
|
||||||
|
color: sshy ? buttonColor : Colors.grey),
|
||||||
|
tooltip: sshy
|
||||||
|
? 'Connect with SSH'
|
||||||
|
: 'SSH server not detected on guest',
|
||||||
onPressed: !sshy
|
onPressed: !sshy
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
TextEditingController _usernameController = TextEditingController();
|
TextEditingController _usernameController =
|
||||||
|
TextEditingController();
|
||||||
showDialog<bool>(
|
showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) => AlertDialog(
|
builder: (BuildContext context) => AlertDialog(
|
||||||
title: Text('Launch SSH connection to $currentVm'),
|
title: Text('Launch SSH connection to $currentVm'),
|
||||||
content: TextField(
|
content: TextField(
|
||||||
controller: _usernameController,
|
controller: _usernameController,
|
||||||
decoration: const InputDecoration(hintText: "SSH username"),
|
decoration: const InputDecoration(
|
||||||
|
hintText: "SSH username"),
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
|
@ -387,10 +408,16 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
|
||||||
).then((result) {
|
).then((result) {
|
||||||
result = result ?? false;
|
result = result ?? false;
|
||||||
if (result) {
|
if (result) {
|
||||||
List<String> sshArgs = ['ssh', '-p', vmInfo.sshPort!, _usernameController.text + '@localhost'];
|
List<String> sshArgs = [
|
||||||
|
'ssh',
|
||||||
|
'-p',
|
||||||
|
vmInfo.sshPort!,
|
||||||
|
_usernameController.text + '@localhost'
|
||||||
|
];
|
||||||
// Set the arguments to execute the ssh command in the default terminal.
|
// Set the arguments to execute the ssh command in the default terminal.
|
||||||
// Strip the extension as x-terminal-emulator may point to a .wrapper
|
// Strip the extension as x-terminal-emulator may point to a .wrapper
|
||||||
switch (path.basenameWithoutExtension(_terminalEmulator!)) {
|
switch (path
|
||||||
|
.basenameWithoutExtension(_terminalEmulator!)) {
|
||||||
case 'gnome-terminal':
|
case 'gnome-terminal':
|
||||||
case 'mate-terminal':
|
case 'mate-terminal':
|
||||||
sshArgs.insert(0, '--');
|
sshArgs.insert(0, '--');
|
||||||
|
|
|
@ -10,7 +10,8 @@ class OperatingSystemSelection extends StatefulWidget {
|
||||||
const OperatingSystemSelection({Key? key}) : super(key: key);
|
const OperatingSystemSelection({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<OperatingSystemSelection> createState() => _OperatingSystemSelectionState();
|
State<OperatingSystemSelection> createState() =>
|
||||||
|
_OperatingSystemSelectionState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
|
class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
|
||||||
|
@ -25,7 +26,9 @@ class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var list = gOperatingSystems.where((os) => os.name.toLowerCase().contains(term.toLowerCase())).toList();
|
var list = gOperatingSystems
|
||||||
|
.where((os) => os.name.toLowerCase().contains(term.toLowerCase()))
|
||||||
|
.toList();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(context.t('Select operating system')),
|
title: Text(context.t('Select operating system')),
|
||||||
|
@ -47,7 +50,8 @@ class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
decoration: InputDecoration.collapsed(hintText: context.t('Search operating system')),
|
decoration: InputDecoration.collapsed(
|
||||||
|
hintText: context.t('Search operating system')),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
term = value;
|
term = value;
|
||||||
|
|
|
@ -24,7 +24,9 @@ class _OptionSelectionState extends State<OptionSelection> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var list = widget.version.options.where((e) => e.option.toLowerCase().contains(term.toLowerCase())).toList();
|
var list = widget.version.options
|
||||||
|
.where((e) => e.option.toLowerCase().contains(term.toLowerCase()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -49,7 +51,8 @@ class _OptionSelectionState extends State<OptionSelection> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
decoration: InputDecoration.collapsed(hintText: context.t('Search option')),
|
decoration: InputDecoration.collapsed(
|
||||||
|
hintText: context.t('Search option')),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
term = value;
|
term = value;
|
||||||
|
|
|
@ -8,7 +8,8 @@ import '../model/version.dart';
|
||||||
import 'option_selection.dart';
|
import 'option_selection.dart';
|
||||||
|
|
||||||
class VersionSelection extends StatefulWidget {
|
class VersionSelection extends StatefulWidget {
|
||||||
const VersionSelection({Key? key, required this.operatingSystem}) : super(key: key);
|
const VersionSelection({Key? key, required this.operatingSystem})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
final OperatingSystem operatingSystem;
|
final OperatingSystem operatingSystem;
|
||||||
|
|
||||||
|
@ -21,7 +22,8 @@ class _VersionSelectionState extends State<VersionSelection> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(context.t('Select version for {0}', args: [widget.operatingSystem.name])),
|
title: Text(context
|
||||||
|
.t('Select version for {0}', args: [widget.operatingSystem.name])),
|
||||||
),
|
),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -36,17 +38,23 @@ class _VersionSelectionState extends State<VersionSelection> {
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(item.version),
|
title: Text(item.version),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (widget.operatingSystem.versions[index].options.length > 1) {
|
if (widget
|
||||||
|
.operatingSystem.versions[index].options.length >
|
||||||
|
1) {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.push<Option>(
|
.push<Option>(MaterialPageRoute(
|
||||||
MaterialPageRoute(fullscreenDialog: true, builder: (context) => OptionSelection(widget.operatingSystem.versions[index])))
|
fullscreenDialog: true,
|
||||||
|
builder: (context) => OptionSelection(
|
||||||
|
widget.operatingSystem.versions[index])))
|
||||||
.then((selection) {
|
.then((selection) {
|
||||||
if (selection != null) {
|
if (selection != null) {
|
||||||
Navigator.of(context).pop(Tuple2<Version, Option?>(item, selection));
|
Navigator.of(context)
|
||||||
|
.pop(Tuple2<Version, Option?>(item, selection));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Navigator.of(context).pop(Tuple2<Version, Option?>(item, widget.operatingSystem.versions[index].options[0]));
|
Navigator.of(context).pop(Tuple2<Version, Option?>(item,
|
||||||
|
widget.operatingSystem.versions[index].options[0]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -21,14 +21,18 @@ class CancelDismissButton extends StatelessWidget {
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
primary: Theme.of(context).colorScheme.surface,
|
primary: Theme.of(context).colorScheme.surface,
|
||||||
onPrimary: Theme.of(context).brightness == Brightness.dark ? Colors.white70 : Theme.of(context).colorScheme.primary,
|
onPrimary: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Colors.white70
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
onPressed: !downloadFinished
|
onPressed: !downloadFinished
|
||||||
? onCancel
|
? onCancel
|
||||||
: () {
|
: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: downloadFinished ? Text(context.t('Dismiss')) : Text(context.t('Cancel')),
|
child: downloadFinished
|
||||||
|
? Text(context.t('Dismiss'))
|
||||||
|
: Text(context.t('Cancel')),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -2,7 +2,12 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:gettext_i18n/gettext_i18n.dart';
|
import 'package:gettext_i18n/gettext_i18n.dart';
|
||||||
|
|
||||||
class DownloadLabel extends StatelessWidget {
|
class DownloadLabel extends StatelessWidget {
|
||||||
const DownloadLabel({Key? key, required this.downloadFinished, required this.data, required this.downloader}) : super(key: key);
|
const DownloadLabel(
|
||||||
|
{Key? key,
|
||||||
|
required this.downloadFinished,
|
||||||
|
required this.data,
|
||||||
|
required this.downloader})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
final bool downloadFinished;
|
final bool downloadFinished;
|
||||||
final double? data;
|
final double? data;
|
||||||
|
@ -17,7 +22,8 @@ class DownloadLabel extends StatelessWidget {
|
||||||
: data != null
|
: data != null
|
||||||
? downloader != 'zsync'
|
? downloader != 'zsync'
|
||||||
? downloader == 'wget'
|
? downloader == 'wget'
|
||||||
? Text(context.t('Downloading...{0}%', args: [(data! * 100).toInt()]))
|
? Text(context.t('Downloading...{0}%',
|
||||||
|
args: [(data! * 100).toInt()]))
|
||||||
: Text(context.t('{0} Mbs downloaded', args: [data!]))
|
: Text(context.t('{0} Mbs downloaded', args: [data!]))
|
||||||
: Text(context.t("Downloading (no progress available)..."))
|
: Text(context.t("Downloading (no progress available)..."))
|
||||||
: Text(context.t('Waiting for download to start')),
|
: Text(context.t('Waiting for download to start')),
|
||||||
|
|
|
@ -26,14 +26,19 @@ class HomePageButton extends StatelessWidget {
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
label?.toUpperCase() ?? '',
|
label?.toUpperCase() ?? '',
|
||||||
style: Theme.of(context).textTheme.subtitle2?.copyWith(color: Colors.white),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.subtitle2
|
||||||
|
?.copyWith(color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
primary: Theme.of(context).canvasColor,
|
primary: Theme.of(context).canvasColor,
|
||||||
onPrimary: Theme.of(context).brightness == Brightness.dark ? Colors.white70 : Theme.of(context).colorScheme.primary,
|
onPrimary: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Colors.white70
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|
|
@ -27,7 +27,8 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var _versionButtonLabel = _selectedVersion?.version ?? context.t('Select...');
|
var _versionButtonLabel =
|
||||||
|
_selectedVersion?.version ?? context.t('Select...');
|
||||||
if (_selectedOption?.option.isNotEmpty ?? false) {
|
if (_selectedOption?.option.isNotEmpty ?? false) {
|
||||||
_versionButtonLabel = "$_versionButtonLabel (${_selectedOption!.option})";
|
_versionButtonLabel = "$_versionButtonLabel (${_selectedOption!.option})";
|
||||||
}
|
}
|
||||||
|
@ -38,12 +39,15 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
text: _selectedOperatingSystem?.name ?? context.t('Select...'),
|
text: _selectedOperatingSystem?.name ?? context.t('Select...'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.push<OperatingSystem>(MaterialPageRoute(fullscreenDialog: true, builder: (context) => const OperatingSystemSelection()))
|
.push<OperatingSystem>(MaterialPageRoute(
|
||||||
|
fullscreenDialog: true,
|
||||||
|
builder: (context) => const OperatingSystemSelection()))
|
||||||
.then((selection) {
|
.then((selection) {
|
||||||
if (selection != null) {
|
if (selection != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedOperatingSystem = selection;
|
_selectedOperatingSystem = selection;
|
||||||
if (selection.versions.length == 1 && selection.versions.first.options.length == 1) {
|
if (selection.versions.length == 1 &&
|
||||||
|
selection.versions.first.options.length == 1) {
|
||||||
_selectedVersion = selection.versions.first;
|
_selectedVersion = selection.versions.first;
|
||||||
_selectedOption = selection.versions.first.options.first;
|
_selectedOption = selection.versions.first.options.first;
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,7 +67,8 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.push<Tuple2<Version, Option?>>(MaterialPageRoute(
|
.push<Tuple2<Version, Option?>>(MaterialPageRoute(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
builder: (context) => VersionSelection(operatingSystem: _selectedOperatingSystem!),
|
builder: (context) => VersionSelection(
|
||||||
|
operatingSystem: _selectedOperatingSystem!),
|
||||||
))
|
))
|
||||||
.then((selection) {
|
.then((selection) {
|
||||||
if (selection != null) {
|
if (selection != null) {
|
||||||
|
@ -115,14 +120,21 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 32),
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
||||||
child: Text(context.t('Downloading...'), style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white)),
|
child: Text(context.t('Downloading...'),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyText1
|
||||||
|
?.copyWith(color: Colors.white)),
|
||||||
),
|
),
|
||||||
const CircularProgressIndicator(),
|
const CircularProgressIndicator(),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 32),
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Target : ${Directory.current.absolute.path}',
|
'Target : ${Directory.current.absolute.path}',
|
||||||
style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyText1
|
||||||
|
?.copyWith(color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -137,7 +149,8 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showDoneDialog({required String operatingSystem, required String version}) {
|
void showDoneDialog(
|
||||||
|
{required String operatingSystem, required String version}) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
|
@ -155,10 +168,19 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 32),
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
||||||
child: Text(context.t('Done !'), style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white)),
|
child: Text(context.t('Done !'),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyText1
|
||||||
|
?.copyWith(color: Colors.white)),
|
||||||
),
|
),
|
||||||
Text(context.t('Now run {0} to start the VM', args: ["quickemu --vm $operatingSystem-$version"]),
|
Text(
|
||||||
style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white)),
|
context.t('Now run {0} to start the VM',
|
||||||
|
args: ["quickemu --vm $operatingSystem-$version"]),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyText1
|
||||||
|
?.copyWith(color: Colors.white)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 32),
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
|
@ -167,7 +189,10 @@ class _HomePageButtonGroupState extends State<HomePageButtonGroup> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Dismiss',
|
'Dismiss',
|
||||||
style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyText1
|
||||||
|
?.copyWith(color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -12,7 +12,9 @@ class MainMenu extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context).brightness == Brightness.dark ? Theme.of(context).colorScheme.surface : Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Theme.of(context).colorScheme.surface
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -23,7 +25,8 @@ class MainMenu extends StatelessWidget {
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
pageBuilder: (context, animation1, animation2) => const Manager(),
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
const Manager(),
|
||||||
transitionDuration: Duration.zero,
|
transitionDuration: Duration.zero,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -36,7 +39,8 @@ class MainMenu extends StatelessWidget {
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
pageBuilder: (context, animation1, animation2) => const DownloaderPage(),
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
const DownloaderPage(),
|
||||||
transitionDuration: Duration.zero,
|
transitionDuration: Duration.zero,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue