From c355f9ff5c7b9d0886e37b52c88acedb98f676fb Mon Sep 17 00:00:00 2001 From: Levi Date: Sun, 13 Sep 2026 18:56:37 +0800 Subject: [PATCH] fix: retain zero download speed for known-size tasks --- .../features/tasks/domain/task_record.dart | 2 +- .../widgets/task_card/task_card_parts.dart | 2 +- ui/flutter/test/widget_test.dart | 72 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/ui/flutter/lib/features/tasks/domain/task_record.dart b/ui/flutter/lib/features/tasks/domain/task_record.dart index 44a5a426..47aa0cd4 100644 --- a/ui/flutter/lib/features/tasks/domain/task_record.dart +++ b/ui/flutter/lib/features/tasks/domain/task_record.dart @@ -133,7 +133,7 @@ class TaskRecord { status: status, downloaded: _formatBytes(downloadedBytes), total: totalBytes > 0 ? _formatBytes(totalBytes) : null, - speed: task.progress.speed > 0 ? TransferRateFormatter.format(task.progress.speed).text : null, + speed: totalBytes > 0 || task.progress.speed > 0 ? TransferRateFormatter.format(task.progress.speed).text : null, uploadSpeed: task.uploading ? TransferRateFormatter.format(task.progress.uploadSpeed).text : null, remainingSeconds: _remainingSeconds(task, totalBytes, downloadedBytes), downloadDuration: task.progress.used > 0 ? Duration(microseconds: (task.progress.used + 999) ~/ 1000) : null, diff --git a/ui/flutter/lib/features/tasks/presentation/widgets/task_card/task_card_parts.dart b/ui/flutter/lib/features/tasks/presentation/widgets/task_card/task_card_parts.dart index ac08f324..51c27537 100644 --- a/ui/flutter/lib/features/tasks/presentation/widgets/task_card/task_card_parts.dart +++ b/ui/flutter/lib/features/tasks/presentation/widgets/task_card/task_card_parts.dart @@ -106,7 +106,7 @@ class TaskCardFooter extends StatelessWidget { ), ), const SizedBox(width: 12), - if (task.speed != null && !isError) ...[ + if (task.speed != null) ...[ _TaskTransferSpeed(icon: Icons.south, value: task.speed!, color: metaColor), const SizedBox(width: 8), TickDivider(color: palette.progressTrack), diff --git a/ui/flutter/test/widget_test.dart b/ui/flutter/test/widget_test.dart index 72362d2d..4b71c1d3 100644 --- a/ui/flutter/test/widget_test.dart +++ b/ui/flutter/test/widget_test.dart @@ -3385,6 +3385,78 @@ void main() { expect(record.isIndeterminate, isTrue); }); + test('known total size preserves zero download speed independently of task status', () { + for (final status in api_task.Status.values) { + for (final total in [0, 1024]) { + for (final speed in [0, 512]) { + final task = _apiTransferTask(id: 'speed', status: status, uploading: false, speed: speed, uploadSpeed: 0); + task.meta.res = Resource(size: total, files: []); + expect(TaskRecord.fromApi(task).speed, total > 0 || speed > 0 ? '$speed B/s' : isNull); + } + } + } + }); + + for (final width in [390.0, 1024.0]) { + testWidgets('known-size task cards retain zero download speed at width $width', (tester) async { + await _setTestSize(tester, Size(width, 220)); + for (final status in api_task.Status.values) { + final task = _apiTransferTask(id: 'zero-speed', status: status, uploading: false, speed: 0, uploadSpeed: 0); + task.meta.res = Resource(size: 1024, files: []); + await tester.pumpWidget( + shad.ShadcnApp( + theme: AppTheme.light(), + materialTheme: AppTheme.materialLight(), + home: Padding( + padding: const EdgeInsets.all(24), + child: TaskCard( + task: TaskRecord.fromApi(task), + selected: false, + batchMode: false, + selectedInBatch: false, + onPressed: () {}, + onToggleBatch: () {}, + ), + ), + ), + ); + await tester.pump(); + expect(find.text('0 B/s'), findsOneWidget); + expect(find.byIcon(Icons.south), findsOneWidget); + expect(tester.takeException(), isNull); + } + }); + } + + testWidgets('known-size task details retain zero download speed', (tester) async { + await _setTestSize(tester, const Size(700, 900)); + final task = _apiTransferTask( + id: 'zero-details', + status: api_task.Status.running, + uploading: false, + speed: 0, + uploadSpeed: 0, + ); + task.meta.res = Resource(size: 1024, files: []); + await tester.pumpWidget( + ProviderScope( + child: shad.ShadcnApp( + theme: AppTheme.light(), + materialTheme: AppTheme.materialLight(), + home: TaskDetailsView( + task: TaskRecord.fromApi(task), + mobile: true, + onOpenStorage: () {}, + onUpdateUrl: (_) async {}, + ), + ), + ), + ); + await tester.pumpAndSettle(); + expect(find.text('0 B/s'), findsOneWidget); + expect(tester.takeException(), isNull); + }); + test('task records preserve zero upload speed while uploading', () { final record = TaskRecord.fromApi( _apiTransferTask(id: 'seeding', status: api_task.Status.done, uploading: true, speed: 0, uploadSpeed: 0),