diff --git a/.gitignore b/.gitignore index 8c89582..ba55d79 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ android/ windows/ list.csv *.xz +*.iso +*.conf diff --git a/README.md b/README.md index e58e4b2..b567c53 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,11 @@ If there are some options (Windows language, Pop!_OS nvidia or Intel, etc..), th ![Option is diplayed](./assets/github/screenshot9.png) -Then click "Download". The ISO will be downloaded in the current working directory, in 99% of cases that will be the directory where `quickgui` was invoked from. The spinner will tell you where the file is being downloaded. +Then click "Download". The ISO will be downloaded in the current working directory, in 99% of cases that will be the directory where `quickgui` was invoked from. -![All set !](./assets/github/screenshot6.png) +![Waiting for download](./assets/github/screenshot10.png) -![Downloading](./assets/github/screenshot7.png) +![Downloading](./assets/github/screenshot11.png) + +![Download finished](./assets/github/screenshot12.png) diff --git a/assets/github/screenshot10.png b/assets/github/screenshot10.png new file mode 100644 index 0000000..a4b8840 Binary files /dev/null and b/assets/github/screenshot10.png differ diff --git a/assets/github/screenshot11.png b/assets/github/screenshot11.png new file mode 100644 index 0000000..d7301a5 Binary files /dev/null and b/assets/github/screenshot11.png differ diff --git a/assets/github/screenshot12.png b/assets/github/screenshot12.png new file mode 100644 index 0000000..1798135 Binary files /dev/null and b/assets/github/screenshot12.png differ diff --git a/lib/src/pages/downloader.dart b/lib/src/pages/downloader.dart new file mode 100644 index 0000000..bf7baf2 --- /dev/null +++ b/lib/src/pages/downloader.dart @@ -0,0 +1,130 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:quickgui/src/model/operating_system.dart'; +import 'package:quickgui/src/model/version.dart'; + +class Downloader extends StatefulWidget { + const Downloader({ + Key? key, + required this.operatingSystem, + required this.version, + this.option, + }) : super(key: key); + + final OperatingSystem operatingSystem; + final Version version; + final String? option; + + @override + _DownloaderState createState() => _DownloaderState(); +} + +class _DownloaderState extends State { + final pattern = RegExp("( [0-9]+%)"); + late final Stream _progressStream; + bool _downloadFinished = false; + + @override + void initState() { + _progressStream = progressStream(); + super.initState(); + } + + Stream progressStream() { + var options = [widget.operatingSystem.code, widget.version.version]; + if (widget.option != null) { + options.add(widget.option!); + } + var controller = StreamController(); + Process.start('quickget', options).then((process) { + process.stderr.transform(utf8.decoder).forEach((line) { + var matches = pattern.allMatches(line).toList(); + if (matches.isNotEmpty) { + var percent = matches[0].group(1); + if (percent != null) { + var value = double.parse(percent.replaceAll('%', '')) / 100.0; + controller.add(value); + } + } + }); + process.exitCode.then((value) { + controller.close(); + setState(() { + _downloadFinished = true; + }); + }); + }); + return controller.stream; + } + + @override + Widget build(BuildContext context) { + //process.then((process) { + // process.stderr.transform(utf8.decoder).forEach((e) { + // var matches = pattern.allMatches(e).toList(); + // var percent = matches[0].group(1); + // if (percent != null) {} + // }); + //}); + + return Scaffold( + appBar: AppBar( + title: Text('Downloading ${widget.operatingSystem.name} ${widget.version.version}' + (widget.option != null ? ' (${widget.option})' : '')), + automaticallyImplyLeading: false, + ), + body: Column(children: [ + Expanded( + child: StreamBuilder( + stream: _progressStream, + builder: (context, AsyncSnapshot snapshot) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: _downloadFinished + ? const Text('Download finished.') + : snapshot.hasData + ? Text('Downloading...${(snapshot.data! * 100).toInt()}%') + : const Text('Waiting for download to start'), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: SizedBox( + width: 200, + child: LinearProgressIndicator( + value: _downloadFinished + ? 1 + : snapshot.hasData + ? snapshot.data! + : null, + ), + ), + ), + ], + ); + }, + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: _downloadFinished + ? () { + Navigator.of(context).pop(); + } + : null, + child: _downloadFinished ? const Text('Dimiss') : const Text('Cancel')) + ], + ), + ), + ]), + ); + } +} diff --git a/lib/src/widgets/home_page_buttons.dart b/lib/src/widgets/home_page_buttons.dart index 54eebfc..b4aad4f 100644 --- a/lib/src/widgets/home_page_buttons.dart +++ b/lib/src/widgets/home_page_buttons.dart @@ -1,9 +1,11 @@ +import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:quickgui/src/model/operating_system.dart'; import 'package:quickgui/src/model/version.dart'; +import 'package:quickgui/src/pages/downloader.dart'; import 'package:quickgui/src/pages/operating_system_selection.dart'; import 'package:quickgui/src/pages/version_selection.dart'; import 'package:quickgui/src/widgets/home_page_button.dart'; @@ -72,11 +74,28 @@ class _HomePageButtonsState extends State { text: 'Download', onPressed: (_selectedVersion == null) ? null - : () async { + : () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => Downloader( + operatingSystem: _selectedOperatingSystem!, + version: _selectedVersion!, + option: _selectedOption, + ))); + /* showLoadingIndicator(text: 'Downloading'); - await Process.run('quickget', [_selectedOperatingSystem!.code, _selectedVersion!.version]); + //await Process.run('quickget', [_selectedOperatingSystem!.code, _selectedVersion!.version]); + var options = [_selectedOperatingSystem!.code, _selectedVersion!.version]; + if (_selectedOption != null) { + options.add(_selectedOption!); + } + var process = await Process.start('quickget', options); + process.stderr.transform(utf8.decoder).forEach( + + ); + var exitCode = await process.exitCode; hideLoadingIndicator(); showDoneDialog(operatingSystem: _selectedOperatingSystem!.code, version: _selectedVersion!.version); + */ }, ), ], diff --git a/pubspec.yaml b/pubspec.yaml index f6fb5c1..49d3e3a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+3 +version: 1.0.0+4 environment: sdk: ">=2.12.0 <3.0.0"