mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
225 lines
6.1 KiB
Dart
225 lines
6.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:venera/components/components.dart';
|
|
import 'package:venera/foundation/app.dart';
|
|
import 'package:venera/foundation/image_provider/cached_image.dart';
|
|
import 'package:venera/foundation/local.dart';
|
|
import 'package:venera/network/download.dart';
|
|
import 'package:venera/utils/io.dart';
|
|
import 'package:venera/utils/translations.dart';
|
|
|
|
class DownloadingPage extends StatefulWidget {
|
|
const DownloadingPage({super.key});
|
|
|
|
@override
|
|
State<DownloadingPage> createState() => _DownloadingPageState();
|
|
}
|
|
|
|
class _DownloadingPageState extends State<DownloadingPage> {
|
|
@override
|
|
void initState() {
|
|
LocalManager().addListener(update);
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
LocalManager().removeListener(update);
|
|
super.dispose();
|
|
}
|
|
|
|
void update() {
|
|
if(mounted) {
|
|
setState(() {});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return PopUpWidgetScaffold(
|
|
title: "",
|
|
body: ListView.builder(
|
|
itemCount: LocalManager().downloadingTasks.length + 1,
|
|
itemBuilder: (BuildContext context, int i) {
|
|
if (i == 0) {
|
|
return buildTop();
|
|
}
|
|
i--;
|
|
|
|
return _DownloadTaskTile(
|
|
task: LocalManager().downloadingTasks[i],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget buildTop() {
|
|
int speed = 0;
|
|
if (LocalManager().downloadingTasks.isNotEmpty) {
|
|
speed = LocalManager().downloadingTasks.first.speed;
|
|
}
|
|
var first = LocalManager().downloadingTasks.firstOrNull;
|
|
return Container(
|
|
height: 48,
|
|
decoration: BoxDecoration(
|
|
border: Border(
|
|
bottom: BorderSide(
|
|
color: context.colorScheme.outlineVariant,
|
|
width: 0.6,
|
|
),
|
|
),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
if (first?.isPaused == true)
|
|
Text(
|
|
"Paused".tl,
|
|
style: ts.s18.bold,
|
|
)
|
|
else if (first?.isError == true)
|
|
Text(
|
|
"Error".tl,
|
|
style: ts.s18.bold,
|
|
)
|
|
else
|
|
Text(
|
|
"${bytesToReadableString(speed)}/s",
|
|
style: ts.s18.bold,
|
|
),
|
|
const Spacer(),
|
|
if (first?.isPaused == true || first?.isError == true)
|
|
OutlinedButton(
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.play_arrow, size: 18),
|
|
const SizedBox(width: 4),
|
|
Text("Start".tl),
|
|
],
|
|
),
|
|
onPressed: () {
|
|
first!.resume();
|
|
},
|
|
)
|
|
else if (first != null)
|
|
OutlinedButton(
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.pause, size: 18),
|
|
const SizedBox(width: 4),
|
|
Text("Pause".tl),
|
|
],
|
|
),
|
|
onPressed: () {
|
|
first.pause();
|
|
},
|
|
),
|
|
],
|
|
).paddingHorizontal(16),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _DownloadTaskTile extends StatefulWidget {
|
|
const _DownloadTaskTile({required this.task});
|
|
|
|
final DownloadTask task;
|
|
|
|
@override
|
|
State<_DownloadTaskTile> createState() => _DownloadTaskTileState();
|
|
}
|
|
|
|
class _DownloadTaskTileState extends State<_DownloadTaskTile> {
|
|
@override
|
|
void initState() {
|
|
widget.task.addListener(update);
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
widget.task.removeListener(update);
|
|
super.dispose();
|
|
}
|
|
|
|
void update() {
|
|
context.findAncestorStateOfType<_DownloadingPageState>()?.update();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
height: 136,
|
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
width: 82,
|
|
height: double.infinity,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(8),
|
|
color: context.colorScheme.primaryContainer,
|
|
),
|
|
clipBehavior: Clip.antiAlias,
|
|
child: widget.task.cover == null
|
|
? null
|
|
: Image(
|
|
image: CachedImageProvider(widget.task.cover!),
|
|
filterQuality: FilterQuality.medium,
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
widget.task.title,
|
|
style: Theme.of(context).textTheme.bodyMedium,
|
|
maxLines: 2,
|
|
),
|
|
),
|
|
MenuButton(
|
|
entries: [
|
|
MenuEntry(
|
|
icon: Icons.close,
|
|
text: "Cancel".tl,
|
|
onClick: () {
|
|
widget.task.cancel();
|
|
},
|
|
),
|
|
MenuEntry(
|
|
icon: Icons.vertical_align_top,
|
|
text: "Move To First".tl,
|
|
onClick: () {
|
|
LocalManager().moveToFirst(widget.task);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
const Spacer(),
|
|
if (!widget.task.isPaused || widget.task.isError)
|
|
Text(
|
|
widget.task.message,
|
|
style: ts.s12,
|
|
maxLines: 3,
|
|
),
|
|
const SizedBox(height: 4),
|
|
LinearProgressIndicator(
|
|
value: widget.task.progress,
|
|
),
|
|
const SizedBox(height: 8),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|