mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-09 10:00:27 +00:00
feat: support browse files on web (#283)
This commit is contained in:
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();
|
||||
}
|
||||
Reference in new issue
Block a user