Closing to initial release
This commit is contained in:
parent
09104a1f9c
commit
c49a7900aa
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -4,7 +4,7 @@ import 'package:window_size/window_size.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
setWindowTitle('QuickUI : a flutter frontend for Quickget and Quickemu');
|
setWindowTitle('Quickgui : a flutter frontend for Quickget and Quickemu');
|
||||||
setWindowMinSize(const Size(692, 580));
|
setWindowMinSize(const Size(692, 580));
|
||||||
setWindowMaxSize(const Size(692, 580));
|
setWindowMaxSize(const Size(692, 580));
|
||||||
runApp(const App());
|
runApp(const App());
|
||||||
|
|
|
@ -7,11 +7,10 @@ class App extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Flutter Demo',
|
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: Colors.pink,
|
primarySwatch: Colors.pink,
|
||||||
),
|
),
|
||||||
home: const MainPage(title: 'QuickUI - A Flutter frontend for Quickget and Quickemu'),
|
home: const MainPage(title: 'Quickgui - A Flutter frontend for Quickget and Quickemu'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
class OperatingSystem {
|
||||||
|
OperatingSystem({required this.name, this.code, this.hasMore = false});
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final String? code;
|
||||||
|
final bool hasMore;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
class Version {
|
||||||
|
Version({required this.name, this.code});
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final String? code;
|
||||||
|
}
|
|
@ -1,5 +1,11 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.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/operating_system_page.dart';
|
import 'package:quickgui/src/pages/operating_system_page.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';
|
import 'package:quickgui/src/widgets/home_page_button.dart';
|
||||||
|
|
||||||
class MainPage extends StatefulWidget {
|
class MainPage extends StatefulWidget {
|
||||||
|
@ -12,6 +18,9 @@ class MainPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MainPageState extends State<MainPage> {
|
class _MainPageState extends State<MainPage> {
|
||||||
|
OperatingSystem? _selectedOperatingSystem;
|
||||||
|
Version? _selectedVersion;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -21,10 +30,13 @@ class _MainPageState extends State<MainPage> {
|
||||||
height: 250,
|
height: 250,
|
||||||
child: Flex(
|
child: Flex(
|
||||||
direction: Axis.vertical,
|
direction: Axis.vertical,
|
||||||
children: const [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text("QuickGui"),
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Image.asset('assets/images/logo.png'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -36,23 +48,60 @@ class _MainPageState extends State<MainPage> {
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
HomePageButton(
|
child: Row(
|
||||||
text: "Operating system",
|
children: [
|
||||||
onPressed: () {
|
HomePageButton(
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const OperatingSystemPpage()));
|
label: "Operating system",
|
||||||
},
|
text: _selectedOperatingSystem?.name ?? 'Select...',
|
||||||
),
|
onPressed: () {
|
||||||
const HomePageButton(
|
Navigator.of(context)
|
||||||
text: "Version",
|
.push<OperatingSystem>(MaterialPageRoute(fullscreenDialog: true, builder: (context) => const OperatingSystemSelection()))
|
||||||
onPressed: null,
|
.then((selection) {
|
||||||
),
|
if (selection != null) {
|
||||||
const HomePageButton(
|
setState(() {
|
||||||
text: "Download",
|
_selectedOperatingSystem = selection;
|
||||||
onPressed: null,
|
_selectedVersion = null;
|
||||||
),
|
});
|
||||||
],
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
HomePageButton(
|
||||||
|
label: "Version",
|
||||||
|
text: _selectedVersion?.name ?? 'Select...',
|
||||||
|
onPressed: (_selectedOperatingSystem != null)
|
||||||
|
? () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.push<Version>(MaterialPageRoute(
|
||||||
|
fullscreenDialog: true,
|
||||||
|
builder: (context) => VersionSelection(operatingSystem: _selectedOperatingSystem!),
|
||||||
|
))
|
||||||
|
.then((selection) {
|
||||||
|
if (selection != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectedVersion = selection;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
HomePageButton(
|
||||||
|
text: 'Download',
|
||||||
|
onPressed: (_selectedVersion == null)
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
showLoadingIndicator(text: 'Downloading');
|
||||||
|
await Process.run('quickget', [_selectedOperatingSystem!.code!, _selectedVersion!.code!]);
|
||||||
|
print('Finished !');
|
||||||
|
hideOpenDialog();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -62,4 +111,44 @@ class _MainPageState extends State<MainPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showLoadingIndicator({String text = ''}) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => WillPopScope(
|
||||||
|
onWillPop: () async => false,
|
||||||
|
child: AlertDialog(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.black87,
|
||||||
|
content: SizedBox(
|
||||||
|
height: 200,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
||||||
|
child: Text('Downloading...', style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white)),
|
||||||
|
),
|
||||||
|
const CircularProgressIndicator(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
||||||
|
child: Text(
|
||||||
|
'Target : ${Directory.current.absolute.path}',
|
||||||
|
style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hideOpenDialog() {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:quickgui/src/model/operating_system.dart';
|
||||||
|
import 'package:quiver/iterables.dart';
|
||||||
|
|
||||||
|
class OperatingSystemSelection extends StatefulWidget {
|
||||||
|
const OperatingSystemSelection({Key? key, this.showUbuntus = false}) : super(key: key);
|
||||||
|
|
||||||
|
final bool showUbuntus;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<OperatingSystemSelection> createState() => _OperatingSystemSelectionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
|
||||||
|
late Future<List<OperatingSystem>> _future;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_future = loadOperatingSystems(widget.showUbuntus);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Select operating system'),
|
||||||
|
),
|
||||||
|
body: FutureBuilder<List<OperatingSystem>>(
|
||||||
|
future: _future,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: snapshot.data!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var item = snapshot.data![index];
|
||||||
|
return Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(item.name),
|
||||||
|
trailing: item.hasMore ? const Icon(Icons.chevron_right) : null,
|
||||||
|
onTap: () {
|
||||||
|
if (!item.hasMore) {
|
||||||
|
Navigator.of(context).pop(item);
|
||||||
|
} else {
|
||||||
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(
|
||||||
|
fullscreenDialog: true,
|
||||||
|
builder: (context) => const OperatingSystemSelection(
|
||||||
|
showUbuntus: true,
|
||||||
|
)))
|
||||||
|
.then((selection) {
|
||||||
|
if (selection != null) {
|
||||||
|
Navigator.of(context).pop(selection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<OperatingSystem>> loadOperatingSystems(bool showUbuntus) async {
|
||||||
|
return Process.run('quickget', []).then<List<OperatingSystem>>((process) {
|
||||||
|
var stdout = process.stdout as String;
|
||||||
|
var codes = stdout.split('\n')[1].split(' ').where((element) => showUbuntus ? element.contains('buntu') : !element.contains('buntu'));
|
||||||
|
var names = codes.map((code) => code.toLowerCase().split('-').map((e) => e[0].toUpperCase() + e.substring(1)).join(' '));
|
||||||
|
List<OperatingSystem> items = [];
|
||||||
|
if (!showUbuntus) items.add(OperatingSystem(name: 'Ubuntu', hasMore: true));
|
||||||
|
items.addAll(zip([codes, names]).map((item) => OperatingSystem(code: item[0], name: item[1])).toList());
|
||||||
|
items.sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
|
||||||
|
return items;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:quickgui/src/model/operating_system.dart';
|
||||||
|
import 'package:quickgui/src/model/version.dart';
|
||||||
|
import 'package:quiver/iterables.dart';
|
||||||
|
|
||||||
|
class VersionSelection extends StatefulWidget {
|
||||||
|
const VersionSelection({Key? key, required this.operatingSystem}) : super(key: key);
|
||||||
|
|
||||||
|
final OperatingSystem operatingSystem;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_VersionSelectionState createState() => _VersionSelectionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VersionSelectionState extends State<VersionSelection> {
|
||||||
|
late Future<List<Version>> _future;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_future = loadOperatingSystemVersions();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Select version for ${widget.operatingSystem.name}'),
|
||||||
|
),
|
||||||
|
body: FutureBuilder<List<Version>>(
|
||||||
|
future: _future,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: snapshot.data!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var item = snapshot.data![index];
|
||||||
|
return Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(item.name),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop(item);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Version>> loadOperatingSystemVersions() async {
|
||||||
|
return Process.run('quickget', [widget.operatingSystem.code!, 'dummy']).then<List<Version>>((process) {
|
||||||
|
var stdout = process.stdout as String;
|
||||||
|
var versions = stdout.split('\n')[1].split(' ');
|
||||||
|
var names =
|
||||||
|
versions.map((version) => version.toLowerCase().split('-').map((e) => e[0].toUpperCase() + e.substring(1)).join(' ').split('_').join('.')).toList();
|
||||||
|
List<Version> items = [];
|
||||||
|
items.addAll(zip([versions, names]).map((e) => Version(code: e[0], name: e[1])));
|
||||||
|
|
||||||
|
return items;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,33 +1,47 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class HomePageButton extends StatelessWidget {
|
class HomePageButton extends StatelessWidget {
|
||||||
final String text;
|
|
||||||
final VoidCallback? onPressed;
|
|
||||||
|
|
||||||
const HomePageButton({
|
const HomePageButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
this.label,
|
||||||
required this.text,
|
required this.text,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String? label;
|
||||||
|
final String text;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(24.0),
|
padding: const EdgeInsets.fromLTRB(12, 24, 12, 24),
|
||||||
child: ElevatedButton(
|
child: Column(
|
||||||
style: ElevatedButton.styleFrom(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
primary: Colors.white,
|
children: [
|
||||||
onPrimary: Colors.pink,
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.only(bottom: 24),
|
||||||
onPressed: onPressed,
|
child: Center(
|
||||||
child: Padding(
|
child: Text(
|
||||||
padding: const EdgeInsets.fromLTRB(0, 16, 0, 16),
|
label?.toUpperCase() ?? '',
|
||||||
child: Text(
|
style: Theme.of(context).textTheme.subtitle2?.copyWith(color: Colors.white),
|
||||||
text.toUpperCase(),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.white,
|
||||||
|
onPrimary: Colors.pink,
|
||||||
|
),
|
||||||
|
onPressed: onPressed,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 16, 0, 16),
|
||||||
|
child: Text(text),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,8 @@
|
||||||
|
Package: quickgui
|
||||||
|
Version: 1.0.0-1
|
||||||
|
Section: base
|
||||||
|
Priority: optional
|
||||||
|
Architecture: amd64
|
||||||
|
Maintainer: Yannick Mauray <yannick@frenchguy.ch>
|
||||||
|
Description: Flutter frontend for Quickget
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
{"assets/images/logo.png":["assets/images/logo.png"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]}
|
|
@ -0,0 +1 @@
|
||||||
|
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}]
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
{"app_name":"quickgui","version":"1.0.0","build_number":"1"}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -38,6 +38,7 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: git://github.com/google/flutter-desktop-embedding.git
|
url: git://github.com/google/flutter-desktop-embedding.git
|
||||||
path: plugins/window_size
|
path: plugins/window_size
|
||||||
|
quiver: ^3.0.1+1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -65,6 +66,8 @@ flutter:
|
||||||
# assets:
|
# assets:
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
assets:
|
||||||
|
- assets/images/logo.png
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||||
|
|
Loading…
Reference in New Issue