mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-08 17:40:28 +00:00
feat: task detail view (#633)
This commit is contained in:
22 files changed
+280
-105
No files matched your search
@@ -380,7 +380,7 @@ jobs:
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
go get golang.org/x/mobile/bind
|
||||
gomobile init
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg=com.gopeed github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s -X github.com/GopeedLab/gopeed/pkg/base.Version=$VERSION" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg=com.gopeed github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
echo $APK_KEYSTORE | base64 -di > android/app/upload-keystore.jks
|
||||
flutter build apk
|
||||
|
||||
@@ -174,7 +174,7 @@ command:
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+1
-1
@@ -162,7 +162,7 @@ gomobile init
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ command:
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ gomobile init
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ gomobile init
|
||||
- android
|
||||
|
||||
```bash
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 21 -javapkg="com.gopeed" github.com/GopeedLab/gopeed/bind/mobile
|
||||
cd ui/flutter
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
@@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
compileSdkVersion 34
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
@@ -47,7 +47,7 @@ android {
|
||||
applicationId "com.gopeed"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
minSdkVersion 21
|
||||
minSdkVersion 32
|
||||
targetSdkVersion 29
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
<application
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Gopeed">
|
||||
android:label="Gopeed"
|
||||
android:extractNativeLibs="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
|
||||
@@ -195,7 +195,8 @@ class AppController extends GetxController with WindowListener, TrayListener {
|
||||
} else if (Util.isMacos()) {
|
||||
await trayManager.setIcon('assets/tray_icon/icon_mac.png',
|
||||
isTemplate: true);
|
||||
} else if (Platform.environment.containsKey('FLATPAK_ID') || Platform.environment.containsKey('SNAP')) {
|
||||
} else if (Platform.environment.containsKey('FLATPAK_ID') ||
|
||||
Platform.environment.containsKey('SNAP')) {
|
||||
await trayManager.setIcon('com.gopeed.Gopeed');
|
||||
} else {
|
||||
await trayManager.setIcon('assets/tray_icon/icon.png');
|
||||
@@ -269,16 +270,12 @@ class AppController extends GetxController with WindowListener, TrayListener {
|
||||
|
||||
FlutterForegroundTask.init(
|
||||
androidNotificationOptions: AndroidNotificationOptions(
|
||||
channelId: 'gopeed_service',
|
||||
channelName: 'Gopeed Background Service',
|
||||
channelImportance: NotificationChannelImportance.LOW,
|
||||
showWhen: true,
|
||||
priority: NotificationPriority.LOW,
|
||||
iconData: const NotificationIconData(
|
||||
resType: ResourceType.mipmap,
|
||||
resPrefix: ResourcePrefix.ic,
|
||||
name: 'launcher',
|
||||
)),
|
||||
channelId: 'gopeed_service',
|
||||
channelName: 'Gopeed Background Service',
|
||||
channelImportance: NotificationChannelImportance.LOW,
|
||||
showWhen: true,
|
||||
priority: NotificationPriority.LOW,
|
||||
),
|
||||
iosNotificationOptions: const IOSNotificationOptions(
|
||||
showNotification: true,
|
||||
playSound: false,
|
||||
@@ -298,6 +295,11 @@ class AppController extends GetxController with WindowListener, TrayListener {
|
||||
FlutterForegroundTask.startService(
|
||||
notificationTitle: "serviceTitle".tr,
|
||||
notificationText: "serviceText".tr,
|
||||
notificationIcon: const NotificationIconData(
|
||||
resType: ResourceType.mipmap,
|
||||
resPrefix: ResourcePrefix.ic,
|
||||
name: 'launcher',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import 'dart:io';
|
||||
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:gopeed/app/views/copy_button.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:launch_at_startup/launch_at_startup.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
@@ -842,6 +844,32 @@ class SettingView extends GetView<SettingController> {
|
||||
);
|
||||
});
|
||||
|
||||
// advanced config log items start
|
||||
buildLogsDir() {
|
||||
return ListTile(
|
||||
title: Text("日志目录"),
|
||||
subtitle: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: TextEditingController(text: logsDir()),
|
||||
enabled: false,
|
||||
readOnly: true,
|
||||
),
|
||||
),
|
||||
Util.isDesktop()
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.folder_open),
|
||||
onPressed: () {
|
||||
launchUrl(Uri.file(logsDir()));
|
||||
},
|
||||
)
|
||||
: CopyButton(logsDir()),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
return Obx(() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
@@ -953,6 +981,13 @@ class SettingView extends GetView<SettingController> {
|
||||
: null,
|
||||
]),
|
||||
)),
|
||||
const Text('开发者'),
|
||||
Card(
|
||||
child: Column(
|
||||
children: _addDivider([
|
||||
buildLogsDir(),
|
||||
]),
|
||||
)),
|
||||
]),
|
||||
))
|
||||
],
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:gopeed/api/model/task.dart';
|
||||
|
||||
class TaskController extends GetxController {
|
||||
final tabIndex = 0.obs;
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final selectTask = Rx<Task?>(null);
|
||||
final copyUrlDone = false.obs;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ class TaskFilesView extends GetView<TaskFilesController> {
|
||||
}()
|
||||
: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.play_circle),
|
||||
icon: const Icon(Icons.open_in_new),
|
||||
onPressed: () async {
|
||||
await OpenFilex.open(filePath);
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:open_filex/open_filex.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../../../../api/model/task.dart';
|
||||
import '../../../../util/file_explorer.dart';
|
||||
import '../../../../util/util.dart';
|
||||
import '../../../routes/app_pages.dart';
|
||||
import '../../../views/copy_button.dart';
|
||||
import '../controllers/task_controller.dart';
|
||||
import '../controllers/task_downloaded_controller.dart';
|
||||
import '../controllers/task_downloading_controller.dart';
|
||||
@@ -12,9 +19,12 @@ class TaskView extends GetView<TaskController> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final selectTask = controller.selectTask;
|
||||
|
||||
return DefaultTabController(
|
||||
length: 2,
|
||||
child: Scaffold(
|
||||
key: controller.scaffoldKey,
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(56),
|
||||
child: AppBar(
|
||||
@@ -54,7 +64,118 @@ class TaskView extends GetView<TaskController> {
|
||||
TaskDownloadedView(),
|
||||
],
|
||||
),
|
||||
endDrawer: Drawer(
|
||||
// Add a ListView to the drawer. This ensures the user can scroll
|
||||
// through the options in the drawer if there isn't enough vertical
|
||||
// space to fit everything.
|
||||
child: Obx(() => ListView(
|
||||
// Important: Remove any padding from the ListView.
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).padding.top + 65,
|
||||
child: DrawerHeader(
|
||||
child: Text(
|
||||
'taskDetail'.tr,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
)),
|
||||
),
|
||||
ListTile(
|
||||
title: Text('taskName'.tr),
|
||||
subtitle:
|
||||
buildTooltipSubtitle(selectTask.value?.showName)),
|
||||
ListTile(
|
||||
title: Text('taskUrl'.tr),
|
||||
subtitle:
|
||||
buildTooltipSubtitle(selectTask.value?.meta.req.url),
|
||||
trailing: CopyButton(selectTask.value?.meta.req.url),
|
||||
),
|
||||
ListTile(
|
||||
title: Text('downloadPath'.tr),
|
||||
subtitle:
|
||||
buildTooltipSubtitle(selectTask.value?.explorerUrl),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.folder_open),
|
||||
onPressed: () {
|
||||
selectTask.value?.explorer();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTooltipSubtitle(String? text) {
|
||||
final showText = text ?? "";
|
||||
return Tooltip(
|
||||
message: showText,
|
||||
child: Text(
|
||||
showText,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension TaskEnhance on Task {
|
||||
String get showName {
|
||||
if (meta.opts.name.isNotEmpty) {
|
||||
return meta.opts.name;
|
||||
}
|
||||
if (meta.res == null) {
|
||||
final u = Uri.parse(meta.req.url);
|
||||
if (u.scheme.startsWith("http")) {
|
||||
return u.path.isNotEmpty
|
||||
? u.path.substring(u.path.lastIndexOf("/") + 1)
|
||||
: u.host;
|
||||
} else {
|
||||
final params = u.queryParameters;
|
||||
if (params.containsKey("dn")) {
|
||||
return params["dn"]!;
|
||||
} else {
|
||||
return params["xt"]!.split(":").last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (meta.res!.name.isNotEmpty) {
|
||||
return meta.res!.name;
|
||||
}
|
||||
return meta.res!.files[0].name;
|
||||
}
|
||||
|
||||
bool get isFolder {
|
||||
return meta.res?.name.isNotEmpty ?? false;
|
||||
}
|
||||
|
||||
String get explorerUrl {
|
||||
if (isFolder) {
|
||||
return path.join(Util.safeDir(meta.opts.path),
|
||||
Util.safeDir(meta.res!.files[0].path), showName);
|
||||
} else {
|
||||
return path.join(Util.safeDir(meta.opts.path), Util.safeDir(showName));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> explorer() async {
|
||||
if (Util.isDesktop()) {
|
||||
await FileExplorer.openAndSelectFile(explorerUrl);
|
||||
} else {
|
||||
Get.rootDelegate.toNamed(Routes.TASK_FILES, parameters: {'id': id});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> open() async {
|
||||
if (status != Status.done) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFolder) {
|
||||
await explorer();
|
||||
} else {
|
||||
await OpenFilex.open(explorerUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:open_filex/open_filex.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';
|
||||
import '../../util/icons.dart';
|
||||
import '../../util/message.dart';
|
||||
import '../../util/util.dart';
|
||||
import '../modules/app/controllers/app_controller.dart';
|
||||
import '../modules/task/controllers/task_controller.dart';
|
||||
import '../modules/task/views/task_view.dart';
|
||||
import '../routes/app_pages.dart';
|
||||
|
||||
class BuildTaskListView extends GetView {
|
||||
@@ -60,17 +58,7 @@ class BuildTaskListView extends GetView {
|
||||
}
|
||||
|
||||
bool isFolderTask() {
|
||||
return task.meta.res?.name.isNotEmpty ?? false;
|
||||
}
|
||||
|
||||
String buildExplorerUrl(Task task) {
|
||||
if (!isFolderTask()) {
|
||||
return path.join(Util.safeDir(task.meta.opts.path),
|
||||
Util.safeDir(task.meta.res!.files[0].path), fileName(task.meta));
|
||||
} else {
|
||||
return path.join(Util.safeDir(task.meta.opts.path),
|
||||
Util.safeDir(fileName(task.meta)));
|
||||
}
|
||||
return task.isFolder;
|
||||
}
|
||||
|
||||
Future<void> showDeleteDialog(String id) {
|
||||
@@ -119,22 +107,13 @@ class BuildTaskListView extends GetView {
|
||||
));
|
||||
}
|
||||
|
||||
toTaskFilesView() {
|
||||
if (Util.isDesktop()) {
|
||||
FileExplorer.openAndSelectFile(buildExplorerUrl(task));
|
||||
} else {
|
||||
Get.rootDelegate
|
||||
.toNamed(Routes.TASK_FILES, parameters: {'id': task.id});
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> buildActions() {
|
||||
final list = <Widget>[];
|
||||
if (isDone()) {
|
||||
list.add(IconButton(
|
||||
icon: const Icon(Icons.folder_open),
|
||||
onPressed: () {
|
||||
toTaskFilesView();
|
||||
task.explorer();
|
||||
},
|
||||
));
|
||||
} else {
|
||||
@@ -188,27 +167,26 @@ class BuildTaskListView extends GetView {
|
||||
(total > 0 ? " / ${Util.fmtByte(total)}" : "");
|
||||
}
|
||||
|
||||
final taskController = Get.find<TaskController>();
|
||||
|
||||
return Card(
|
||||
elevation: 4.0,
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
taskController.scaffoldKey.currentState?.openEndDrawer();
|
||||
taskController.selectTask.value = task;
|
||||
},
|
||||
onDoubleTap: () {
|
||||
if (isDone()) {
|
||||
if (isFolderTask()) {
|
||||
toTaskFilesView();
|
||||
} else {
|
||||
OpenFilex.open(buildExplorerUrl(task));
|
||||
}
|
||||
}
|
||||
task.open();
|
||||
},
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(fileName(task.meta)),
|
||||
title: Text(task.showName),
|
||||
leading: isFolderTask()
|
||||
? const Icon(FaIcons.folder)
|
||||
: Icon(FaIcons.allIcons[findIcon(fileName(task.meta))])),
|
||||
: Icon(FaIcons.allIcons[findIcon(task.showName)])),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
@@ -239,29 +217,4 @@ class BuildTaskListView extends GetView {
|
||||
),
|
||||
)).padding(horizontal: 14, top: 8);
|
||||
}
|
||||
|
||||
String fileName(Meta meta) {
|
||||
if (meta.opts.name.isNotEmpty) {
|
||||
return meta.opts.name;
|
||||
}
|
||||
if (meta.res == null) {
|
||||
final u = Uri.parse(meta.req.url);
|
||||
if (u.scheme.startsWith("http")) {
|
||||
return u.path.isNotEmpty
|
||||
? u.path.substring(u.path.lastIndexOf("/") + 1)
|
||||
: u.host;
|
||||
} else {
|
||||
final params = u.queryParameters;
|
||||
if (params.containsKey("dn")) {
|
||||
return params["dn"]!;
|
||||
} else {
|
||||
return params["xt"]!.split(":").last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (meta.res!.name.isNotEmpty) {
|
||||
return meta.res!.name;
|
||||
}
|
||||
return meta.res!.files[0].name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../../util/message.dart';
|
||||
|
||||
class CopyButton extends StatefulWidget {
|
||||
final String? url;
|
||||
|
||||
const CopyButton(this.url, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CopyButton> createState() => _CopyButtonState();
|
||||
}
|
||||
|
||||
class _CopyButtonState extends State<CopyButton> {
|
||||
bool success = false;
|
||||
|
||||
copy() {
|
||||
final url = widget.url;
|
||||
if (url != null) {
|
||||
try {
|
||||
Clipboard.setData(ClipboardData(text: url));
|
||||
setState(() {
|
||||
success = true;
|
||||
});
|
||||
Future.delayed(const Duration(milliseconds: 300), () {
|
||||
setState(() {
|
||||
success = false;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
showErrorMessage(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: success ? const Icon(Icons.check_circle) : const Icon(Icons.copy),
|
||||
onPressed: copy,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -99,5 +99,9 @@ const enUS = {
|
||||
'seedKeep': 'Keep seeding',
|
||||
'seedRatio': 'Seed ratio',
|
||||
'seedTime': 'Seed time (minutes)',
|
||||
'taskDetail': 'Task Detail',
|
||||
'taskName': 'Task Name',
|
||||
'taskUrl': 'Task URL',
|
||||
'downloadPath': 'Download Path',
|
||||
},
|
||||
};
|
||||
@@ -96,5 +96,9 @@ const zhCN = {
|
||||
'seedKeep': '持续做种',
|
||||
'seedRatio': '做种分享率',
|
||||
'seedTime': '做种时间(分钟)',
|
||||
'taskDetail': '任务详情',
|
||||
'taskName': '任务名称',
|
||||
'taskUrl': '任务链接',
|
||||
'downloadPath': '下载路径',
|
||||
}
|
||||
};
|
||||
@@ -96,5 +96,15 @@ const zhTW = {
|
||||
'seedKeep': '持續做種',
|
||||
'seedRatio': '做種分享率',
|
||||
'seedTime': '做種時間(分鐘)',
|
||||
/*
|
||||
'taskDetail': '任务详情',
|
||||
'taskName': '任务名称',
|
||||
'taskUrl': '任务链接',
|
||||
'downloadPath': '下载路径',
|
||||
*/
|
||||
'taskDetail': '任務詳情',
|
||||
'taskName': '任務名稱',
|
||||
'taskUrl': '任務連結',
|
||||
'downloadPath': '下載路徑',
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class FileExplorer {
|
||||
static Future<void> openAndSelectFile(String filePath) async {
|
||||
if (await FileSystemEntity.isFile(filePath)) {
|
||||
@@ -10,17 +12,7 @@ class FileExplorer {
|
||||
}
|
||||
|
||||
static Future<void> _openDirectory(String directoryPath) async {
|
||||
if (Platform.isWindows) {
|
||||
Process.run('explorer.exe', [directoryPath]);
|
||||
} else if (Platform.isMacOS) {
|
||||
Process.run('open', [directoryPath]);
|
||||
} else if (Platform.isLinux) {
|
||||
if (await _isUbuntuOrDebian()) {
|
||||
Process.run('xdg-open', [directoryPath]);
|
||||
} else if (await _isCentOS()) {
|
||||
Process.run('nautilus', [directoryPath]);
|
||||
}
|
||||
}
|
||||
await launchUrlString("file://$directoryPath");
|
||||
}
|
||||
|
||||
static Future<void> _openFile(String filePath) async {
|
||||
|
||||
@@ -15,11 +15,15 @@ initLogger() {
|
||||
);
|
||||
}
|
||||
|
||||
String logsDir() {
|
||||
return path.join(Util.getStorageDir(), 'logs');
|
||||
}
|
||||
|
||||
_buildOutput() {
|
||||
// if is debug mode, don't log to file
|
||||
if (!kDebugMode && Util.isDesktop()) {
|
||||
final logDirPath = path.join(Util.getStorageDir(), 'logs');
|
||||
var logDir = Directory(logDirPath);
|
||||
final logDirPath = logsDir();
|
||||
var logDir = Directory(logsDir());
|
||||
if (!logDir.existsSync()) {
|
||||
logDir.createSync();
|
||||
}
|
||||
|
||||
+10
-10
@@ -322,10 +322,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_foreground_task
|
||||
sha256: "6cf10a27f5e344cd2ecad0752d3a5f4ec32846d82fda8753b3fe2480ebb832a3"
|
||||
sha256: "294280d8055af5628a8085bb765ba442561eaab3d5bcdf2eea4f20614f18618f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
version: "8.2.0"
|
||||
flutter_form_builder:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -681,10 +681,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.3.2"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -841,10 +841,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "671e7a931f55a08aa45be2a13fe7247f2a41237897df434b30d2012388191833"
|
||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.3.5"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1054,10 +1054,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
|
||||
sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.1"
|
||||
version: "6.2.4"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1195,5 +1195,5 @@ packages:
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
sdks:
|
||||
dart: ">=3.2.3 <4.0.0"
|
||||
flutter: ">=3.16.6"
|
||||
dart: ">=3.2.0 <4.0.0"
|
||||
flutter: ">=3.16.0"
|
||||
@@ -59,7 +59,7 @@ dependencies:
|
||||
share_plus: ^7.1.0
|
||||
flutter_form_builder: ^9.1.1
|
||||
form_builder_validators: ^9.0.0
|
||||
flutter_foreground_task: ^6.1.2
|
||||
flutter_foreground_task: ^8.2.0
|
||||
open_filex: ^4.3.4
|
||||
tray_manager: ^0.2.3
|
||||
lecle_downloads_path_provider: ^0.0.2+8
|
||||
|
||||
Reference in new issue
Block a user