Improve OS loading

Rather than waiting for the OS list to load, when the app starts, the
loads them in the background, and only waits if we reach the list of
available downloads without them loaded yet. In this case, we use a
FutureBuilder to display a loading spinner until the list is ready.
This commit is contained in:
Mark Johnson 2024-06-21 15:26:15 +01:00 committed by Martin Wimpress
parent 208d4f8dc9
commit 3c23106d32
4 changed files with 53 additions and 31 deletions

View File

@ -80,7 +80,7 @@ void main() async {
setWindowMaxSize(const Size(692, 580)); setWindowMaxSize(const Size(692, 580));
final foundQuickGet = await Process.run('which', ['quickget']); final foundQuickGet = await Process.run('which', ['quickget']);
if (foundQuickGet.exitCode == 0) { if (foundQuickGet.exitCode == 0) {
gOperatingSystems = await loadOperatingSystems(false); gOperatingSystems = loadOperatingSystems(false);
getIcons(); getIcons();
AppVersion.packageInfo = await PackageInfo.fromPlatform(); AppVersion.packageInfo = await PackageInfo.fromPlatform();
} }

View File

@ -8,4 +8,4 @@ class OperatingSystem {
List<Version> versions; List<Version> versions;
} }
var gOperatingSystems = <OperatingSystem>[]; Future<List<OperatingSystem>>? gOperatingSystems;

View File

@ -25,9 +25,6 @@ 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();
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(context.t('Select operating system')), title: Text(context.t('Select operating system')),
@ -69,36 +66,61 @@ class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
body: SingleChildScrollView( body: SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
ListView.builder( FutureBuilder(
padding: const EdgeInsets.only(top: 4), future: gOperatingSystems,
shrinkWrap: true, builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
itemCount: list.length, if (snapshot.hasData) {
itemBuilder: (context, index) { List list = snapshot.data!
var item = list[index]; .where((os) => os.name.toLowerCase().contains(term.toLowerCase()))
Widget icon; .toList();
return ListView.builder(
padding: const EdgeInsets.only(top: 4),
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index) {
var item = list[index];
Widget icon;
if (osIcons.containsKey(item.code)) { if (osIcons.containsKey(item.code)) {
icon = SvgPicture.asset( icon = SvgPicture.asset(
osIcons[item.code]!, osIcons[item.code]!,
width: 32, width: 32,
height: 32, height: 32,
);
} else {
// Replace with generic icon
icon = const Icon(Icons.computer, size: 32);
}
return Card(
child: ListTile(
title: Text(item.name),
leading: icon,
onTap: () {
Navigator.of(context).pop(item);
},
),
);
},
); );
} else { } else {
// Replace with generic icon return Row(
icon = const Icon(Icons.computer, size: 32); mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: CircularProgressIndicator()
),
Text(context.t('Loading available downloads')),
],
)
],
);
} }
return Card( }
child: ListTile(
title: Text(item.name),
leading: icon,
onTap: () {
Navigator.of(context).pop(item);
},
),
);
},
), ),
], ]
), ),
), ),
); );

View File

@ -4,7 +4,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.2.8-1 version: 1.2.8-1
environment: environment:
sdk: ">=2.14.4 <3.0.0" sdk: ">=2.15.0 <3.0.0"
dependencies: dependencies:
flutter: flutter: