From 71a3859ab9ea039cf63e1f9a6fbcaa5207fc179f Mon Sep 17 00:00:00 2001 From: qu1ck Date: Thu, 12 Oct 2023 22:08:27 -0700 Subject: [PATCH] Add "Open folder" item in torrent/file row menu Issue #92 --- src-tauri/Cargo.lock | 23 +++++++++++++++++++++++ src-tauri/Cargo.toml | 2 +- src-tauri/src/commands.rs | 9 +++++---- src/components/tables/filetreetable.tsx | 18 ++++++++++++------ src/components/tables/torrenttable.tsx | 19 +++++++++++++------ 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 4cf071d..1449df4 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -826,6 +826,17 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" +[[package]] +name = "dbus" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +dependencies = [ + "libc", + "libdbus-sys", + "winapi", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1933,6 +1944,16 @@ version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +[[package]] +name = "libdbus-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2444,7 +2465,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" dependencies = [ "bstr", + "dbus", "normpath", + "url", "winapi", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5e33277..d798b9e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -25,7 +25,7 @@ tokio = { version = "^1.28", features = ["net"] } serde = { version = "^1.0", features = ["derive"] } tauri = { version = "^1.4", features = [ "clipboard-write-text", "cli", "devtools", "dialog-all", "fs-read-file", "fs-write-file", "notification", "path-all", "shell-open", "system-tray", "window-center", "window-close", "window-create", "window-hide", "window-set-focus", "window-set-position", "window-set-size", "window-set-title", "window-show", "window-unminimize"] } tauri-utils = "^1.4" -opener = "0.6" +opener = { version = "0.6", features = ["reveal"] } rodio = { version = "0.17.1", features = ["mp3"], default-features = false } hyper-tls = "0.5.0" notify-rust = "4.8.0" diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 486852d..c9ce6d1 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -59,7 +59,6 @@ pub async fn read_file(path: String) -> Result { return Err(format!("Failed to read file {:?}", path)); } - match Torrent::read_from_bytes(&read_result.as_ref().unwrap()[..]) { Err(_) => Err(format!("Failed to parse torrent {:?}", path)), Ok(torrent) => { @@ -105,12 +104,14 @@ pub async fn remove_file(path: String) { } #[tauri::command] -pub async fn shell_open(path: String) -> Result<(), String> { +pub async fn shell_open(path: String, reveal: bool) -> Result<(), String> { #[cfg(target_os = "windows")] let path = path.replace('/', "\\"); - if let Err(e) = opener::open(path) { - return Err(e.to_string()); + if reveal { + opener::reveal(path).map_err(|e| e.to_string())? + } else { + opener::open(path).map_err(|e| e.to_string())? } Ok(()) } diff --git a/src/components/tables/filetreetable.tsx b/src/components/tables/filetreetable.tsx index 3ff7851..177a7df 100644 --- a/src/components/tables/filetreetable.tsx +++ b/src/components/tables/filetreetable.tsx @@ -287,7 +287,7 @@ export function FileTreeTable(props: FileTreeTableProps) { selectedReducer({ verb: "set", ids: [], isReset: true }); }, [props.fileTree.torrenthash, selectedReducer]); - const onRowDoubleClick = useCallback((row: FileDirEntry) => { + const onRowDoubleClick = useCallback((row: FileDirEntry, reveal: boolean = false) => { if (TAURI) { if (props.downloadDir === undefined || props.downloadDir === "") return; let path = props.downloadDir; @@ -296,7 +296,7 @@ export function FileTreeTable(props: FileTreeTableProps) { } path = path + row.fullpath + (isDirEntry(row) ? "/" : ""); path = pathMapFromServer(path, serverConfig); - invoke("shell_open", { path }).catch((e) => { + invoke("shell_open", { path, reveal }).catch((e) => { notifications.show({ title: "Error opening path", message: path, @@ -389,16 +389,16 @@ function FiletreeContextMenu(props: { setContextMenuInfo: (i: ContextMenuInfo) => void, fileTree: CachedFileTree, selected: string[], - onRowDoubleClick: (row: FileDirEntry) => void, + onRowDoubleClick: (row: FileDirEntry, reveal: boolean) => void, setExpanded?: (state: boolean) => void, toggleFileSearchBox: () => void, }) { const { onRowDoubleClick } = props; - const onOpen = useCallback(() => { + const onOpen = useCallback((reveal: boolean) => { const [path] = [...props.selected]; const entry = props.fileTree.findEntry(path); if (entry === undefined) return; - onRowDoubleClick(entry); + onRowDoubleClick(entry, reveal); }, [onRowDoubleClick, props.fileTree, props.selected]); const mutation = useMutateTorrent(); @@ -459,11 +459,17 @@ function FiletreeContextMenu(props: { {TAURI && <> { onOpen(false); }} icon={} disabled={props.selected.length !== 1}> Open + { onOpen(true); }} + icon={} + disabled={props.selected.length !== 1}> + Open folder + } { + const onRowDoubleClick = useCallback((torrent: Torrent, reveal: boolean = false) => { if (TAURI) { if (torrent.downloadDir === undefined || torrent.downloadDir === "") return; let path = torrent.downloadDir as string; @@ -410,7 +410,7 @@ export function TorrentTable(props: { } path = path + fileSystemSafeName(torrent.name); path = pathMapFromServer(path, serverConfig); - invoke("shell_open", { path }).catch((e) => { + invoke("shell_open", { path, reveal }).catch((e) => { notifications.show({ title: "Error opening path", message: path, @@ -454,17 +454,17 @@ function TorrentContextMenu(props: { contextMenuInfo: ContextMenuInfo, setContextMenuInfo: (i: ContextMenuInfo) => void, modals: React.RefObject, - onRowDoubleClick: (t: Torrent) => void, + onRowDoubleClick: (t: Torrent, reveal: boolean) => void, }) { const serverData = useServerTorrentData(); const serverSelected = useServerSelectedTorrents(); const { onRowDoubleClick } = props; - const onOpen = useCallback(() => { + const onOpen = useCallback((reveal: boolean) => { const [id] = [...serverSelected]; const torrent = serverData.torrents.find((t) => t.id === id); if (torrent === undefined) return; - onRowDoubleClick(torrent); + onRowDoubleClick(torrent, reveal); }, [onRowDoubleClick, serverData.torrents, serverSelected]); const mutation = useTorrentAction(); @@ -587,12 +587,19 @@ function TorrentContextMenu(props: { {TAURI && <> { onOpen(false); }} onMouseEnter={closeQueueSubmenu} icon={} disabled={serverSelected.size !== 1}> Open + { onOpen(true); }} + onMouseEnter={closeQueueSubmenu} + icon={} + disabled={serverSelected.size !== 1}> + Open folder + }