💄 Optimize downloading and files
This commit is contained in:
@@ -1338,5 +1338,6 @@
|
||||
"enterNumberOfSplits": "Enter Splits Amount",
|
||||
"orCreateWith": "Or\ncreate with",
|
||||
"unindexedFiles": "Unindexed files",
|
||||
"folder": "Folder"
|
||||
"folder": "Folder",
|
||||
"clearCompleted": "Clear Completed"
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,18 +262,14 @@ 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(
|
||||
taskId,
|
||||
DriveTaskStatus.failed,
|
||||
errorMessage: e.toString(),
|
||||
);
|
||||
taskNotifier.updateTaskStatus(
|
||||
taskId,
|
||||
DriveTaskStatus.failed,
|
||||
errorMessage: e.toString(),
|
||||
);
|
||||
showErrorAlert(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user