💄 Optimize downloading and files

This commit is contained in:
2025-11-18 22:21:23 +08:00
parent c8ad791ff3
commit 35b96b0bd2
5 changed files with 53 additions and 73 deletions

View File

@@ -1338,5 +1338,6 @@
"enterNumberOfSplits": "Enter Splits Amount",
"orCreateWith": "Or\ncreate with",
"unindexedFiles": "Unindexed files",
"folder": "Folder"
"folder": "Folder",
"clearCompleted": "Clear Completed"
}

View File

@@ -293,6 +293,10 @@ class UploadTasksNotifier extends StateNotifier<List<DriveTask>> {
.toList();
}
void clearAllTasks() {
state = [];
}
DriveTask? getTask(String taskId) {
return state.where((task) => task.taskId == taskId).firstOrNull;
}

View File

@@ -233,9 +233,8 @@ class FileDetailScreen extends HookConsumerWidget {
}
Future<void> _downloadFile(WidgetRef ref) async {
final taskId = ref
.read(uploadTasksProvider.notifier)
.addLocalDownloadTask(item);
final taskNotifier = ref.read(uploadTasksProvider.notifier);
final taskId = taskNotifier.addLocalDownloadTask(item);
try {
showSnackBar('Downloading file...');
@@ -253,12 +252,8 @@ class FileDetailScreen extends HookConsumerWidget {
queryParameters: {'original': true},
onReceiveProgress: (count, total) {
if (total > 0) {
ref
.read(uploadTasksProvider.notifier)
.updateDownloadProgress(taskId, count, total);
ref
.read(uploadTasksProvider.notifier)
.updateTransmissionProgress(taskId, count / total);
taskNotifier.updateDownloadProgress(taskId, count, total);
taskNotifier.updateTransmissionProgress(taskId, count / total);
}
},
);
@@ -267,14 +262,10 @@ class FileDetailScreen extends HookConsumerWidget {
name: item.name.isEmpty ? '${item.id}.$extName' : item.name,
file: File(filePath),
);
ref
.read(uploadTasksProvider.notifier)
.updateTaskStatus(taskId, DriveTaskStatus.completed);
taskNotifier.updateTaskStatus(taskId, DriveTaskStatus.completed);
showSnackBar('File saved to downloads');
} catch (e) {
ref
.read(uploadTasksProvider.notifier)
.updateTaskStatus(
taskNotifier.updateTaskStatus(
taskId,
DriveTaskStatus.failed,
errorMessage: e.toString(),

View File

@@ -1,8 +1,5 @@
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:file_saver/file_saver.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
@@ -10,16 +7,11 @@ import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/file.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:island/services/time.dart';
import 'package:island/utils/format.dart';
import 'package:island/widgets/alert.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:path/path.dart' show extension;
import 'package:path_provider/path_provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:island/widgets/data_saving_gate.dart';
import 'package:island/widgets/content/file_info_sheet.dart';
import 'file_viewer_contents.dart';
import 'image.dart';
@@ -281,41 +273,13 @@ class CloudFileWidget extends HookConsumerWidget {
'audio' => AudioFileContent(item: item, uri: uri),
_ => Builder(
builder: (context) {
Future<void> downloadFile() async {
try {
showSnackBar('Downloading file...');
final client = ref.read(apiClientProvider);
final tempDir = await getTemporaryDirectory();
var extName = extension(item.name).trim();
if (extName.isEmpty) {
extName = item.mimeType?.split('/').lastOrNull ?? 'bin';
}
final filePath = '${tempDir.path}/${item.id}.$extName';
await client.download(
'/drive/files/${item.id}',
filePath,
queryParameters: {'original': true},
);
await FileSaver.instance.saveFile(
name: item.name.isEmpty ? '${item.id}.$extName' : item.name,
file: File(filePath),
);
showSnackBar('File saved to downloads');
} catch (e) {
showErrorAlert(e);
}
}
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.outline,
width: 1,
),
borderRadius: BorderRadius.circular(8),
borderRadius: BorderRadius.circular(16),
),
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -347,19 +311,12 @@ class CloudFileWidget extends HookConsumerWidget {
Row(
mainAxisSize: MainAxisSize.min,
children: [
TextButton.icon(
onPressed: downloadFile,
icon: const Icon(Symbols.download),
label: Text('download').tr(),
),
const Gap(8),
TextButton.icon(
onPressed: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
isScrollControlled: true,
builder: (context) => FileInfoSheet(item: item),
context.pushNamed(
'fileDetail',
pathParameters: {'id': item.id},
extra: item,
);
},
icon: const Icon(Symbols.info),

View File

@@ -102,7 +102,9 @@ class _UploadOverlayContent extends HookConsumerWidget {
return null;
}, [isExpanded.value]);
final isMobile = MediaQuery.of(context).size.width < 600;
final isMobile = !isWideScreen(context);
final taskNotifier = ref.read(uploadTasksProvider.notifier);
return Padding(
padding: EdgeInsets.only(
@@ -246,7 +248,7 @@ class _UploadOverlayContent extends HookConsumerWidget {
SliverToBoxAdapter(
child: ListTile(
dense: true,
title: const Text('Clear Completed'),
title: const Text('clearCompleted').tr(),
leading: Icon(
Symbols.clear_all,
size: 18,
@@ -256,9 +258,34 @@ class _UploadOverlayContent extends HookConsumerWidget {
).colorScheme.onSurfaceVariant,
),
onTap: () {
ref
.read(uploadTasksProvider.notifier)
.clearCompletedTasks();
taskNotifier.clearCompletedTasks();
isExpanded.value = false;
},
tileColor:
Theme.of(
context,
).colorScheme.surfaceContainerHighest,
),
),
// Clear all tasks button
if (activeTasks.any(
(task) =>
task.status != DriveTaskStatus.completed,
))
SliverToBoxAdapter(
child: ListTile(
dense: true,
title: const Text('Clear All'),
leading: Icon(
Symbols.clear_all,
size: 18,
color:
Theme.of(context).colorScheme.error,
),
onTap: () {
taskNotifier.clearAllTasks();
isExpanded.value = false;
},
tileColor: