New downloader, with progress indicator.

This commit is contained in:
Yannick Mauray 2021-10-21 02:39:51 +02:00
parent 15c09b6884
commit 2f27c161cf
No known key found for this signature in database
GPG Key ID: 67C4AAC5E99CB909
9 changed files with 185 additions and 19 deletions

2
.gitignore vendored
View File

@ -29,3 +29,5 @@ android/
windows/
list.csv
*.xz
*.iso
*.conf

View File

@ -1,20 +1,33 @@
SHELL := /usr/bin/env bash
VERSION := $(shell cat pubspec.yaml | grep "^version: " | cut -c 10- | sed 's/+/\-/')
BUILD_ROOT := ../build-package
BASE_NAME := quickgui-$(VERSION)
BUILD_DIR := $(BUILD_ROOT)/$(BASE_NAME)
BIN_TAR := $(BUILD_ROOT)/$(BASE_NAME).tar
SRC_TAR := $(BUILD_ROOT)/$(BASE_NAME)-src.tar
FLUTTER := /usr/local/bin/flutter
all: prep quickgui clean
all: version bin
prep:
version:
@echo VERSION is $(VERSION)
rm -rf _tmp
mkdir -p _tmp/quickgui
rm -f quickgui-$(VERSION).tar
rm -f quickgui-$(VERSION).tar.xz
@echo BUILD_ROOT is $(BUILD_ROOT)
quickgui:
flutter build linux --release
cp -a build/linux/x64/release/bundle/* _tmp/quickgui
tar -C _tmp -c -f quickgui-$(VERSION).tar quickgui/
xz -z quickgui-$(VERSION).tar
distclean:
$(FLUTTER) clean
rm -rf $(BUILD_ROOT)
clean:
rm -rf _tmp
quickgui: distclean
$(FLUTTER) pub get
$(FLUTTER) build linux --release
bin: quickgui
mkdir -p $(BUILD_DIR)
cp -a build/linux/x64/release/bundle/* $(BUILD_DIR)
tar -C $(BUILD_ROOT) -c -v -f $(BIN_TAR) $(BASE_NAME)
xz -z $(BIN_TAR)
src: distclean
mkdir -p $(BUILD_ROOT)
tar -C .. -c -v -f $(SRC_TAR) --exclude .git --transform 's/^quickgui/$(BASE_NAME)/' quickgui
xz -z $(SRC_TAR)

View File

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -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<Downloader> {
final pattern = RegExp("( [0-9]+%)");
late final Stream<double> _progressStream;
bool _downloadFinished = false;
@override
void initState() {
_progressStream = progressStream();
super.initState();
}
Stream<double> progressStream() {
var options = [widget.operatingSystem.code, widget.version.version];
if (widget.option != null) {
options.add(widget.option!);
}
var controller = StreamController<double>();
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<double> 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'))
],
),
),
]),
);
}
}

View File

@ -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<HomePageButtons> {
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);
*/
},
),
],

View File

@ -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"