feat: support browse files on web (#283)

This commit is contained in:
Levi authored and GitHub committed 2023-11-29 18:24:01 +08:00
1 parent ee7da179c1
commit db15650664
14 files changed
+145 -71

No files matched your search

@@ -1,8 +1,7 @@
import 'package:gopeed/app/modules/task/controllers/task_list_controller.dart';
import '../../../../api/model/task.dart';
class TaskDownloadedController extends TaskListController {
TaskDownloadedController() : super([Status.done]);
TaskDownloadedController() : super([Status.done], SortDirection.asc);
}
@@ -9,5 +9,5 @@ class TaskDownloadingController extends TaskListController {
Status.pause,
Status.wait,
Status.error
]);
], SortDirection.desc);
}
@@ -5,10 +5,13 @@ import 'package:get/get.dart';
import '../../../../api/api.dart';
import '../../../../api/model/task.dart';
enum SortDirection { asc, desc }
abstract class TaskListController extends GetxController {
List<Status> statuses;
SortDirection sortDirection;
TaskListController(this.statuses);
TaskListController(this.statuses, this.sortDirection);
final tasks = <Task>[].obs;
final isRunning = false.obs;
@@ -43,6 +46,15 @@ abstract class TaskListController extends GetxController {
}
getTasksState() async {
tasks.value = await getTasks(statuses);
final tasks = await getTasks(statuses);
// sort tasks by create time
tasks.sort((a, b) {
if (sortDirection == SortDirection.asc) {
return a.createdAt.compareTo(b.createdAt);
} else {
return b.createdAt.compareTo(a.createdAt);
}
});
this.tasks.value = tasks;
}
}
@@ -3,7 +3,10 @@ import 'package:get/get.dart';
import 'package:open_file/open_file.dart';
import 'package:path/path.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../../api/api.dart' as api;
import '../../../../util/browser_download/browser_download.dart';
import '../../../../util/file_icon.dart';
import '../../../../util/icons.dart';
import '../../../../util/util.dart';
@@ -21,7 +24,7 @@ class TaskFilesView extends GetView<TaskFilesController> {
icon: const Icon(Icons.arrow_back),
onPressed: () => Get.rootDelegate.popRoute()),
// actions: [],
title: Obx(() => Text(controller.task.value!.meta.res!.name)),
title: Obx(() => Text(controller.task.value?.meta.res?.name ?? "")),
),
body: Obx(() {
final fileList = controller.fileList;
@@ -53,11 +56,12 @@ class TaskFilesView extends GetView<TaskFilesController> {
itemBuilder: (context, index) {
final meta = controller.task.value!.meta;
final file = fileList[index];
final filePath = Util.safePathJoin([
meta.opts.path,
meta.res!.name,
file.filePath(meta.opts.name)
]);
// if resource is single file, use opts.name as file name
final realFileName =
meta.res!.name.isEmpty ? file.name : "";
final fileRelativePath = file.filePath(realFileName);
final filePath = Util.safePathJoin(
[meta.opts.path, meta.res!.name, fileRelativePath]);
final fileName = basename(filePath);
return ListTile(
leading: file.isDirectory
@@ -77,19 +81,39 @@ class TaskFilesView extends GetView<TaskFilesController> {
width: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
icon: const Icon(Icons.play_circle),
onPressed: () {
OpenFile.open(filePath);
}),
IconButton(
icon: const Icon(Icons.share),
onPressed: () {
final xfile = XFile(filePath);
Share.shareXFiles([xfile]);
})
],
children: Util.isWeb()
? () {
final accessUrl = api.join(
"/fs/tasks/${controller.task.value!.id}$fileRelativePath");
return [
IconButton(
icon:
const Icon(Icons.play_circle),
onPressed: () {
launchUrl(Uri.parse(accessUrl),
webOnlyWindowName:
"_blank");
}),
IconButton(
icon: const Icon(Icons.download),
onPressed: () {
download(accessUrl, fileName);
})
];
}()
: [
IconButton(
icon: const Icon(Icons.play_circle),
onPressed: () {
OpenFile.open(filePath);
}),
IconButton(
icon: const Icon(Icons.share),
onPressed: () {
final xfile = XFile(filePath);
Share.shareXFiles([xfile]);
})
],
),
),
onTap: () {
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gopeed/app/modules/task/controllers/task_downloading_controller.dart';
import '../controllers/task_downloaded_controller.dart';
import 'task_downloading_view.dart';
import 'task_downloaded_view.dart';
import '../controllers/task_controller.dart';
import '../controllers/task_downloaded_controller.dart';
import '../controllers/task_downloading_controller.dart';
import 'task_downloaded_view.dart';
import 'task_downloading_view.dart';
class TaskView extends GetView<TaskController> {
const TaskView({Key? key}) : super(key: key);
@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gopeed/api/model/meta.dart';
import 'package:path/path.dart' as path;
import 'package:styled_widget/styled_widget.dart';
import '../../api/api.dart';
import '../../api/model/meta.dart';
import '../../api/model/task.dart';
import '../../util/file_explorer.dart';
import '../../util/file_icon.dart';
@@ -110,19 +110,17 @@ class BuildTaskListView extends GetView {
List<Widget> buildActions() {
final list = <Widget>[];
if (isDone()) {
if (Util.isDesktop() || Util.isMobile()) {
list.add(IconButton(
icon: const Icon(Icons.folder_open),
onPressed: () {
if (Util.isDesktop()) {
FileExplorer.openAndSelectFile(buildExplorerUrl(task));
} else {
Get.rootDelegate
.toNamed(Routes.TASK_FILES, parameters: {'id': task.id});
}
},
));
}
list.add(IconButton(
icon: const Icon(Icons.folder_open),
onPressed: () {
if (Util.isDesktop()) {
FileExplorer.openAndSelectFile(buildExplorerUrl(task));
} else {
Get.rootDelegate
.toNamed(Routes.TASK_FILES, parameters: {'id': task.id});
}
},
));
} else {
if (isRunning()) {
list.add(IconButton(
@@ -0,0 +1,4 @@
import 'browser_download_stub.dart'
if (dart.library.html) 'entry/browser_download_browser.dart';
void download(String url, String name) => doDownload(url, name);
@@ -0,0 +1 @@
void doDownload(String url, String name) => throw UnimplementedError();
@@ -0,0 +1,9 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
void doDownload(String url, String name) {
final anchorElement = html.AnchorElement(href: url);
anchorElement.download = name;
anchorElement.target = '_blank';
anchorElement.click();
}