From 1e08ecd8db2d065fbbc303001ebb6f2919c2a1aa Mon Sep 17 00:00:00 2001 From: Li Wei Date: Thu, 4 May 2023 14:32:37 +0800 Subject: [PATCH] fix: file explorer and support select file (#111) --- .../app/views/views/buid_task_list_view.dart | 18 +++++-- ui/flutter/lib/util/file_explorer.dart | 47 +++++++++++++++++++ ui/flutter/lib/util/util.dart | 11 ++--- 3 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 ui/flutter/lib/util/file_explorer.dart diff --git a/ui/flutter/lib/app/views/views/buid_task_list_view.dart b/ui/flutter/lib/app/views/views/buid_task_list_view.dart index 1ef2d468..a1fbb526 100644 --- a/ui/flutter/lib/app/views/views/buid_task_list_view.dart +++ b/ui/flutter/lib/app/views/views/buid_task_list_view.dart @@ -3,9 +3,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:path/path.dart' as path; import '../../../api/api.dart'; import '../../../api/model/task.dart'; +import '../../../util/file_explorer.dart'; import '../../../util/file_icon.dart'; import '../../../util/icons.dart'; import '../../../util/message.dart'; @@ -53,6 +55,18 @@ class BuildTaskListView extends GetView { return task.status == Status.running; } + String buildExplorerUrl(Task task) { + if (task.meta.res.rootDir.trim().isEmpty) { + return path.join( + Util.safeDir(task.meta.opts.path), + Util.safeDir(task.meta.res.files[0].path), + task.meta.res.files[0].name); + } else { + return path.join(Util.safeDir(task.meta.opts.path), + Util.safeDir(task.meta.res.rootDir)); + } + } + Future showDeleteDialog(String id) { final keep = true.obs; @@ -100,9 +114,7 @@ class BuildTaskListView extends GetView { list.add(IconButton( icon: const Icon(Icons.folder_open), onPressed: () async { - final file = File(Util.buildAbsPath(task.meta.opts.path, - task.meta.res.files[0].path, task.meta.res.files[0].name)); - await launchUrl(file.parent.uri); + await FileExplorer.openAndSelectFile(buildExplorerUrl(task)); }, )); } diff --git a/ui/flutter/lib/util/file_explorer.dart b/ui/flutter/lib/util/file_explorer.dart new file mode 100644 index 00000000..61f14f24 --- /dev/null +++ b/ui/flutter/lib/util/file_explorer.dart @@ -0,0 +1,47 @@ +import 'dart:io'; + +class FileExplorer { + static Future openAndSelectFile(String filePath) async { + if (!await FileSystemEntity.isDirectory(filePath) && + !await FileSystemEntity.isFile(filePath)) { + return; + } + if (await FileSystemEntity.isDirectory(filePath)) { + if (Platform.isWindows) { + Process.run('explorer.exe', [filePath]); + } else if (Platform.isMacOS || Platform.isLinux) { + Process.run('xdg-open', [filePath]); + } + } else if (await FileSystemEntity.isFile(filePath)) { + if (Platform.isWindows) { + Process.run('explorer.exe', ['/select,', filePath]); + } else if (Platform.isMacOS) { + Process.run('open', ['-R', filePath]); + } else if (Platform.isLinux) { + if (await _isUbuntuOrDebian()) { + Process.run('xdg-open', [filePath]); + } else if (await _isCentOS()) { + Process.run('nautilus', ['--select', filePath]); + } + } + } + } + + static Future _isUbuntuOrDebian() async { + final result = await Process.run('lsb_release', ['-i']); + if (result.exitCode != 0) { + return false; + } + final output = result.stdout.toString().toLowerCase(); + return output.contains('ubuntu') || output.contains('debian'); + } + + static Future _isCentOS() async { + final result = await Process.run('cat', ['/etc/os-release']); + if (result.exitCode != 0) { + return false; + } + final output = result.stdout.toString().toLowerCase(); + return output.contains('centos'); + } +} diff --git a/ui/flutter/lib/util/util.dart b/ui/flutter/lib/util/util.dart index 1604f663..44caf3c8 100644 --- a/ui/flutter/lib/util/util.dart +++ b/ui/flutter/lib/util/util.dart @@ -3,12 +3,11 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; class Util { - static String buildAbsPath(String dir, String path, String name) { - return (dir == "" ? "" : "$dir/") + buildPath(path, name); - } - - static String buildPath(String path, String name) { - return (path == "" ? "" : "$path/") + name; + static String safeDir(String path) { + if (path == "." || path == "./" || path == ".\\") { + return ""; + } + return path; } static String fmtByte(int byte) {