mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 04:57:23 +00:00
159 lines
4.0 KiB
Dart
159 lines
4.0 KiB
Dart
import 'package:fluent_ui/fluent_ui.dart';
|
|
import 'package:pixes/components/md.dart';
|
|
import 'package:pixes/components/message.dart';
|
|
import 'package:pixes/foundation/app.dart';
|
|
import 'package:pixes/network/download.dart';
|
|
import 'package:pixes/utils/translation.dart';
|
|
|
|
import '../network/network.dart';
|
|
|
|
class BatchDownloadButton extends StatelessWidget {
|
|
const BatchDownloadButton({super.key, required this.request});
|
|
|
|
final Future<Res<List<Illust>>> Function() request;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Button(
|
|
child: const Icon(
|
|
MdIcons.download,
|
|
size: 20,
|
|
),
|
|
onPressed: () {
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
barrierColor: Colors.transparent,
|
|
useRootNavigator: false,
|
|
builder: (context) => _DownloadDialog(request));
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class _DownloadDialog extends StatefulWidget {
|
|
const _DownloadDialog(this.request);
|
|
|
|
final Future<Res<List<Illust>>> Function() request;
|
|
|
|
@override
|
|
State<_DownloadDialog> createState() => _DownloadDialogState();
|
|
}
|
|
|
|
class _DownloadDialogState extends State<_DownloadDialog> {
|
|
int maxCount = 30;
|
|
|
|
int currentCount = 0;
|
|
|
|
bool loading = false;
|
|
|
|
bool cancel = false;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ContentDialog(
|
|
title: Text("Batch download".tl),
|
|
content: SizedBox(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (!loading) Text('${"Maximum number of downloads".tl}:'),
|
|
if (loading) Text("${"Current quantity".tl}: $currentCount"),
|
|
const SizedBox(
|
|
height: 16,
|
|
),
|
|
SizedBox(
|
|
height: 42,
|
|
width: 196,
|
|
child: NumberBox(
|
|
value: maxCount,
|
|
onChanged: (value) {
|
|
if (!loading) {
|
|
setState(() => maxCount = value ?? maxCount);
|
|
}
|
|
},
|
|
allowExpressions: true,
|
|
mode: SpinButtonPlacementMode.inline,
|
|
smallChange: 10,
|
|
largeChange: 30,
|
|
clearButton: false,
|
|
),
|
|
),
|
|
],
|
|
).paddingVertical(8),
|
|
),
|
|
actions: [
|
|
Button(
|
|
child: Text("Cancel".tl),
|
|
onPressed: () {
|
|
cancel = true;
|
|
context.pop();
|
|
}),
|
|
if (!loading)
|
|
FilledButton(onPressed: load, child: Text("Continue".tl))
|
|
else
|
|
FilledButton(
|
|
onPressed: () {},
|
|
child: const SizedBox(
|
|
height: 20,
|
|
width: 64,
|
|
child: Center(
|
|
child: SizedBox.square(
|
|
dimension: 18,
|
|
child: ProgressRing(
|
|
strokeWidth: 1.6,
|
|
),
|
|
),
|
|
),
|
|
))
|
|
],
|
|
);
|
|
}
|
|
|
|
void load() async {
|
|
setState(() {
|
|
loading = true;
|
|
});
|
|
|
|
var request = widget.request();
|
|
|
|
List<Illust> all = [];
|
|
String? nextUrl;
|
|
int retryCount = 0;
|
|
while (nextUrl != "end" && all.length < maxCount) {
|
|
if (nextUrl != null) {
|
|
request = Network().getIllustsWithNextUrl(nextUrl);
|
|
}
|
|
var res = await request;
|
|
if (cancel || !mounted) {
|
|
return;
|
|
}
|
|
if (res.error) {
|
|
retryCount++;
|
|
if (retryCount > 3) {
|
|
setState(() {
|
|
loading = false;
|
|
});
|
|
showToast(context, message: "Error".tl);
|
|
return;
|
|
}
|
|
await Future.delayed(Duration(seconds: 1 << retryCount));
|
|
continue;
|
|
}
|
|
all.addAll(res.data);
|
|
setState(() {
|
|
currentCount = all.length;
|
|
});
|
|
nextUrl = res.subData ?? "end";
|
|
}
|
|
int i = 0;
|
|
for (var illust in all) {
|
|
if (i > maxCount) break;
|
|
DownloadManager().addDownloadingTask(illust);
|
|
i++;
|
|
}
|
|
context.pop();
|
|
}
|
|
}
|