Add eta support

This commit is contained in:
2024-05-25 15:31:21 +08:00
parent ddee58eee0
commit afbda5a587
7 changed files with 59 additions and 8 deletions

View File

@@ -78,8 +78,8 @@ class TaskDownloadSingleProgress {
final DateTime started;
final int downloaded;
final double speed;
@JsonKey(name: 'last_updated')
final int lastUpdated;
@JsonKey(name: 'last_updated', fromJson: _fromJson, toJson: _toJson)
final DateTime lastUpdated;
static DateTime _fromJson(int d) =>
DateTime.fromMillisecondsSinceEpoch(d, isUtc: true);
static int _toJson(DateTime d) => d.millisecondsSinceEpoch;

View File

@@ -45,7 +45,8 @@ TaskDownloadSingleProgress _$TaskDownloadSingleProgressFromJson(
(json['started'] as num).toInt()),
downloaded: (json['downloaded'] as num).toInt(),
speed: (json['speed'] as num).toDouble(),
lastUpdated: (json['last_updated'] as num).toInt(),
lastUpdated: TaskDownloadSingleProgress._fromJson(
(json['last_updated'] as num).toInt()),
);
Map<String, dynamic> _$TaskDownloadSingleProgressToJson(
@@ -61,7 +62,7 @@ Map<String, dynamic> _$TaskDownloadSingleProgressToJson(
'started': TaskDownloadSingleProgress._toJson(instance.started),
'downloaded': instance.downloaded,
'speed': instance.speed,
'last_updated': instance.lastUpdated,
'last_updated': TaskDownloadSingleProgress._toJson(instance.lastUpdated),
};
TaskDownloadProgess _$TaskDownloadProgessFromJson(Map<String, dynamic> json) =>

View File

@@ -94,6 +94,7 @@ class _TaskView extends State<TaskView> {
onTap: () {
context.push("/dialog/task/${widget.task.base.id}");
},
behavior: HitTestBehavior.opaque,
child: Column(children: [
_buildText(context),
LinearPercentIndicator(

View File

@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import '../api/task.dart';
import '../globals.dart';
import '../utils/duration.dart';
import '../utils/filesize.dart';
class _KeyValue extends StatelessWidget {
@@ -151,7 +152,8 @@ class _TaskPage extends State<TaskPage> {
_KeyValue(i18n.totalPages, p.totalPage.toString(), fontSize: 16),
_KeyValue(i18n.downloadedSize2, getFileSize(p.downloadedBytes),
fontSize: 16),
_KeyValue(i18n.speed, "${getFileSize((speed * 1000).toInt())}/s", fontSize: 16),
_KeyValue(i18n.speed, "${getFileSize((speed * 1000).toInt())}/s",
fontSize: 16),
]);
}
int now = 0;
@@ -199,12 +201,21 @@ class _TaskPage extends State<TaskPage> {
}
final p = task.progress as TaskDownloadProgess;
if (p.details.isEmpty) return SliverToBoxAdapter(child: Container());
final i18n = AppLocalizations.of(context)!;
return SliverList.builder(
itemCount: p.details.length,
itemBuilder: (context, index) {
final d = p.details[index];
final percent = d.total == 0 ? 0.0 : d.downloaded / d.total;
final percentText = "${(percent * 100).toStringAsFixed(2)}%";
final avgSpeed = d.started.millisecondsSinceEpoch == 0
? 0.0
: d.downloaded /
(d.lastUpdated.millisecondsSinceEpoch -
d.started.millisecondsSinceEpoch);
final eta = d.total == 0
? double.infinity
: (d.total - d.downloaded) / avgSpeed;
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
SelectableText("${d.name}(${d.width}x${d.height})"),
LinearPercentIndicator(
@@ -223,7 +234,8 @@ class _TaskPage extends State<TaskPage> {
Expanded(
child: Text(
"${getFileSize(d.downloaded)}/${getFileSize(d.total)}")),
Text("${getFileSize((d.speed * 1000).toInt())}/s"),
Text(
"${getFileSize((d.speed * 1000).toInt())}/s${i18n.comma}${fmtDuration(context, eta)}"),
]),
]);
},

View File

@@ -181,5 +181,13 @@
},
"comma": ", ",
"downloadedSize2": "Downloaded size",
"speed": "Speed"
"speed": "Speed",
"days": "{num} days",
"@days": {
"placeholders": {
"num": {
"type": "int"
}
}
}
}

View File

@@ -181,5 +181,13 @@
},
"comma": ",",
"downloadedSize2": "已下载大小",
"speed": "速度"
"speed": "速度",
"days": "{num} 天",
"@days": {
"placeholders": {
"num": {
"type": "int"
}
}
}
}

21
lib/utils/duration.dart Normal file
View File

@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
String fmtDuration(BuildContext context, double ms) {
if (ms.isInfinite) {
return "";
}
final dur = ms.toInt() ~/ 1000;
String re = "";
if (dur >= 86400) {
final i18n = AppLocalizations.of(context)!;
re += "${i18n.days(dur ~/ 86400)} ";
}
if (dur >= 3600) {
re += "${(dur ~/ 3600).toString().padLeft(2, '0')}:";
}
final min = (dur ~/ 60).toString().padLeft(2, '0');
final secs = (dur % 60).toString().padLeft(2, '0');
re += "$min:$secs";
return re;
}