fix(gui): Button to open data directory (#256)

This commit is contained in:
Mohan 2025-01-22 16:29:11 +01:00 committed by GitHub
parent 9e27c6548b
commit c9d3536f36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 187 additions and 24 deletions

View file

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Docs: Added a dedicated page for makers. - Docs: Added a dedicated page for makers.
- Docs: Improved the refund and punish page. - Docs: Improved the refund and punish page.
- ASB: Fixed an issue where the ASB would silently fail if the publication of the Monero refund transaction failed. - ASB: Fixed an issue where the ASB would silently fail if the publication of the Monero refund transaction failed.
- GUI: Add a button to open the data directory for troubleshooting purposes.
## [1.0.0-rc.12] - 2025-01-14 ## [1.0.0-rc.12] - 2025-01-14

144
Cargo.lock generated
View file

@ -9345,6 +9345,28 @@ dependencies = [
"thiserror 1.0.69", "thiserror 1.0.69",
] ]
[[package]]
name = "tauri-plugin-opener"
version = "2.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "635ed7c580dc3cdc61c94097d38ef517d749ffc0141c806d904e68e4b0cf1c2a"
dependencies = [
"dunce",
"glob",
"objc2-app-kit",
"objc2-foundation",
"open",
"schemars",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"thiserror 2.0.4",
"url",
"windows 0.58.0",
"zbus 5.3.0",
]
[[package]] [[package]]
name = "tauri-plugin-process" name = "tauri-plugin-process"
version = "2.0.1" version = "2.0.1"
@ -9388,7 +9410,7 @@ dependencies = [
"thiserror 2.0.4", "thiserror 2.0.4",
"tracing", "tracing",
"windows-sys 0.59.0", "windows-sys 0.59.0",
"zbus", "zbus 4.4.0",
] ]
[[package]] [[package]]
@ -11346,6 +11368,7 @@ dependencies = [
"tauri-build", "tauri-build",
"tauri-plugin-cli", "tauri-plugin-cli",
"tauri-plugin-clipboard-manager", "tauri-plugin-clipboard-manager",
"tauri-plugin-opener",
"tauri-plugin-process", "tauri-plugin-process",
"tauri-plugin-shell", "tauri-plugin-shell",
"tauri-plugin-single-instance", "tauri-plugin-single-instance",
@ -12593,9 +12616,45 @@ dependencies = [
"uds_windows", "uds_windows",
"windows-sys 0.52.0", "windows-sys 0.52.0",
"xdg-home", "xdg-home",
"zbus_macros", "zbus_macros 4.4.0",
"zbus_names", "zbus_names 3.0.0",
"zvariant", "zvariant 4.2.0",
]
[[package]]
name = "zbus"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "192a0d989036cd60a1e91a54c9851fb9ad5bd96125d41803eed79d2e2ef74bd7"
dependencies = [
"async-broadcast",
"async-executor",
"async-fs",
"async-io",
"async-lock 3.4.0",
"async-process",
"async-recursion",
"async-task",
"async-trait",
"blocking",
"enumflags2",
"event-listener 5.3.1",
"futures-core",
"futures-util",
"hex",
"nix 0.29.0",
"ordered-stream",
"serde",
"serde_repr",
"static_assertions",
"tracing",
"uds_windows",
"windows-sys 0.59.0",
"winnow 0.6.20",
"xdg-home",
"zbus_macros 5.3.0",
"zbus_names 4.1.1",
"zvariant 5.2.0",
] ]
[[package]] [[package]]
@ -12608,7 +12667,22 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.90", "syn 2.0.90",
"zvariant_utils", "zvariant_utils 2.1.0",
]
[[package]]
name = "zbus_macros"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3685b5c81fce630efc3e143a4ded235b107f1b1cdf186c3f115529e5e5ae4265"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.90",
"zbus_names 4.1.1",
"zvariant 5.2.0",
"zvariant_utils 3.1.0",
] ]
[[package]] [[package]]
@ -12619,7 +12693,19 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
dependencies = [ dependencies = [
"serde", "serde",
"static_assertions", "static_assertions",
"zvariant", "zvariant 4.2.0",
]
[[package]]
name = "zbus_names"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "519629a3f80976d89c575895b05677cbc45eaf9f70d62a364d819ba646409cc8"
dependencies = [
"serde",
"static_assertions",
"winnow 0.6.20",
"zvariant 5.2.0",
] ]
[[package]] [[package]]
@ -12745,7 +12831,22 @@ dependencies = [
"enumflags2", "enumflags2",
"serde", "serde",
"static_assertions", "static_assertions",
"zvariant_derive", "zvariant_derive 4.2.0",
]
[[package]]
name = "zvariant"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e6b9b5f1361de2d5e7d9fd1ee5f6f7fcb6060618a1f82f3472f58f2b8d4be9"
dependencies = [
"endi",
"enumflags2",
"serde",
"static_assertions",
"winnow 0.6.20",
"zvariant_derive 5.2.0",
"zvariant_utils 3.1.0",
] ]
[[package]] [[package]]
@ -12758,7 +12859,20 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.90", "syn 2.0.90",
"zvariant_utils", "zvariant_utils 2.1.0",
]
[[package]]
name = "zvariant_derive"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "573a8dd76961957108b10f7a45bac6ab1ea3e9b7fe01aff88325dc57bb8f5c8b"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.90",
"zvariant_utils 3.1.0",
] ]
[[package]] [[package]]
@ -12771,3 +12885,17 @@ dependencies = [
"quote", "quote",
"syn 2.0.90", "syn 2.0.90",
] ]
[[package]]
name = "zvariant_utils"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd46446ea2a1f353bfda53e35f17633afa79f4fe290a611c94645c69fe96a50"
dependencies = [
"proc-macro2",
"quote",
"serde",
"static_assertions",
"syn 2.0.90",
"winnow 0.6.20",
]

View file

@ -23,6 +23,7 @@
"@tauri-apps/api": "^2.0.0", "@tauri-apps/api": "^2.0.0",
"@tauri-apps/plugin-cli": "^2.0.0", "@tauri-apps/plugin-cli": "^2.0.0",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0", "@tauri-apps/plugin-clipboard-manager": "^2.0.0",
"@tauri-apps/plugin-opener": "^2.2.5",
"@tauri-apps/plugin-process": "^2.0.0", "@tauri-apps/plugin-process": "^2.0.0",
"@tauri-apps/plugin-shell": "^2.0.0", "@tauri-apps/plugin-shell": "^2.0.0",
"@tauri-apps/plugin-store": "^2.0.0", "@tauri-apps/plugin-store": "^2.0.0",

View file

@ -5,9 +5,10 @@ import PromiseInvokeButton from "renderer/components/PromiseInvokeButton";
import { useAppSelector } from "store/hooks"; import { useAppSelector } from "store/hooks";
import InfoBox from "../../modal/swap/InfoBox"; import InfoBox from "../../modal/swap/InfoBox";
import CliLogsBox from "../../other/RenderedCliLog"; import CliLogsBox from "../../other/RenderedCliLog";
import { initializeContext } from "renderer/rpc"; import { getDataDir, initializeContext } from "renderer/rpc";
import { relaunch } from "@tauri-apps/plugin-process"; import { relaunch } from "@tauri-apps/plugin-process";
import RotateLeftIcon from "@material-ui/icons/RotateLeft"; import RotateLeftIcon from "@material-ui/icons/RotateLeft";
import { revealItemInDir } from "@tauri-apps/plugin-opener";
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
actionsOuter: { actionsOuter: {
@ -66,11 +67,12 @@ export default function DaemonControlBox() {
<PromiseInvokeButton <PromiseInvokeButton
endIcon={<FolderOpenIcon />} endIcon={<FolderOpenIcon />}
isIconButton isIconButton
requiresContext={false}
size="small" size="small"
tooltipTitle="Open the data directory of the Swap Daemon in your file explorer" tooltipTitle="Open the data directory in your file explorer"
onInvoke={() => { onInvoke={async () => {
// TODO: Implement this const dataDir = await getDataDir();
throw new Error("Not implemented"); await revealItemInDir(dataDir);
}} }}
/> />
</Box> </Box>

View file

@ -29,6 +29,7 @@ import {
CheckElectrumNodeResponse, CheckElectrumNodeResponse,
GetMoneroAddressesResponse, GetMoneroAddressesResponse,
TauriBackgroundRefundEvent, TauriBackgroundRefundEvent,
GetDataDirArgs,
} from "models/tauriModel"; } from "models/tauriModel";
import { import {
contextStatusEventReceived, contextStatusEventReceived,
@ -277,3 +278,10 @@ export async function updateAllNodeStatuses() {
export async function getMoneroAddresses(): Promise<GetMoneroAddressesResponse> { export async function getMoneroAddresses(): Promise<GetMoneroAddressesResponse> {
return await invokeNoArgs<GetMoneroAddressesResponse>("get_monero_addresses"); return await invokeNoArgs<GetMoneroAddressesResponse>("get_monero_addresses");
} }
export async function getDataDir(): Promise<string> {
const testnet = isTestnet();
return await invoke<GetDataDirArgs, string>("get_data_dir", {
is_testnet: testnet,
});
}

View file

@ -792,6 +792,13 @@
dependencies: dependencies:
"@tauri-apps/api" "^2.0.0" "@tauri-apps/api" "^2.0.0"
"@tauri-apps/plugin-opener@^2.2.5":
version "2.2.5"
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-opener/-/plugin-opener-2.2.5.tgz#928b917d28d3e8b5bafb90f5f91fb0ed20c27fd4"
integrity sha512-hHsJ9RPWpZvZEPVFaL+d25gABMUMOf/A6ESXnvf/ii9guTukj58WXsAE/SOysXRIhej7kseRCxnOnIMpSCdUsQ==
dependencies:
"@tauri-apps/api" "^2.0.0"
"@tauri-apps/plugin-process@^2.0.0": "@tauri-apps/plugin-process@^2.0.0":
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-process/-/plugin-process-2.0.0.tgz#002fd73f0d7b1ae2a5aacf442aa657e83dc2960b" resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-process/-/plugin-process-2.0.0.tgz#002fd73f0d7b1ae2a5aacf442aa657e83dc2960b"

View file

@ -22,6 +22,7 @@ swap = { path = "../swap", features = [ "tauri" ] }
sysinfo = "=0.32.1" sysinfo = "=0.32.1"
tauri = { version = "^2.0.0", features = [ "config-json5" ] } tauri = { version = "^2.0.0", features = [ "config-json5" ] }
tauri-plugin-clipboard-manager = "^2.0.0" tauri-plugin-clipboard-manager = "^2.0.0"
tauri-plugin-opener = "2.2.5"
tauri-plugin-process = "^2.0.0" tauri-plugin-process = "^2.0.0"
tauri-plugin-shell = "^2.0.0" tauri-plugin-shell = "^2.0.0"
tauri-plugin-store = "^2.0.0" tauri-plugin-store = "^2.0.0"

View file

@ -12,6 +12,7 @@
"process:default", "process:default",
"cli:allow-cli-matches", "cli:allow-cli-matches",
"updater:default", "updater:default",
"process:allow-restart" "process:allow-restart",
"opener:default"
] ]
} }

View file

@ -3,15 +3,9 @@ use std::result::Result;
use std::sync::Arc; use std::sync::Arc;
use swap::cli::{ use swap::cli::{
api::{ api::{
request::{ data, request::{
BalanceArgs, BuyXmrArgs, CancelAndRefundArgs, CheckElectrumNodeArgs, BalanceArgs, BuyXmrArgs, CancelAndRefundArgs, CheckElectrumNodeArgs, CheckElectrumNodeResponse, CheckMoneroNodeArgs, CheckMoneroNodeResponse, ExportBitcoinWalletArgs, GetDataDirArgs, GetHistoryArgs, GetLogsArgs, GetMoneroAddressesArgs, GetSwapInfoArgs, GetSwapInfosAllArgs, ListSellersArgs, MoneroRecoveryArgs, ResumeSwapArgs, SuspendCurrentSwapArgs, WithdrawBtcArgs
CheckElectrumNodeResponse, CheckMoneroNodeArgs, CheckMoneroNodeResponse, }, tauri_bindings::{TauriContextStatusEvent, TauriEmitter, TauriHandle, TauriSettings}, Context, ContextBuilder
ExportBitcoinWalletArgs, GetHistoryArgs, GetLogsArgs, GetMoneroAddressesArgs,
GetSwapInfoArgs, GetSwapInfosAllArgs, ListSellersArgs, MoneroRecoveryArgs,
ResumeSwapArgs, SuspendCurrentSwapArgs, WithdrawBtcArgs,
},
tauri_bindings::{TauriContextStatusEvent, TauriEmitter, TauriHandle, TauriSettings},
Context, ContextBuilder,
}, },
command::{Bitcoin, Monero}, command::{Bitcoin, Monero},
}; };
@ -162,6 +156,7 @@ pub fn run() {
.plugin(tauri_plugin_store::Builder::new().build()) .plugin(tauri_plugin_store::Builder::new().build())
.plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
get_balance, get_balance,
get_monero_addresses, get_monero_addresses,
@ -181,6 +176,7 @@ pub fn run() {
check_monero_node, check_monero_node,
check_electrum_node, check_electrum_node,
get_wallet_descriptor, get_wallet_descriptor,
get_data_dir
]) ])
.setup(setup) .setup(setup)
.build(tauri::generate_context!()) .build(tauri::generate_context!())
@ -221,6 +217,7 @@ tauri_command!(monero_recovery, MoneroRecoveryArgs);
tauri_command!(get_logs, GetLogsArgs); tauri_command!(get_logs, GetLogsArgs);
tauri_command!(list_sellers, ListSellersArgs); tauri_command!(list_sellers, ListSellersArgs);
tauri_command!(cancel_and_refund, CancelAndRefundArgs); tauri_command!(cancel_and_refund, CancelAndRefundArgs);
// These commands require no arguments // These commands require no arguments
tauri_command!(get_wallet_descriptor, ExportBitcoinWalletArgs, no_args); tauri_command!(get_wallet_descriptor, ExportBitcoinWalletArgs, no_args);
tauri_command!(suspend_current_swap, SuspendCurrentSwapArgs, no_args); tauri_command!(suspend_current_swap, SuspendCurrentSwapArgs, no_args);
@ -252,6 +249,17 @@ async fn check_electrum_node(
args.request().await.to_string_result() args.request().await.to_string_result()
} }
// Returns the data directory
// This is independent of the context to ensure the user can open the directory even if the context cannot
// be initialized (for troubleshooting purposes)
#[tauri::command]
async fn get_data_dir(
args: GetDataDirArgs,
_: tauri::State<'_, RwLock<State>>,
) -> Result<String, String> {
Ok(data::data_dir_from(None, args.is_testnet).to_string_result()?.to_string_lossy().to_string())
}
/// Tauri command to initialize the Context /// Tauri command to initialize the Context
#[tauri::command] #[tauri::command]
async fn initialize_context( async fn initialize_context(

View file

@ -577,7 +577,7 @@ async fn init_monero_wallet(
Ok((monero_wallet, monero_wallet_rpc_process)) Ok((monero_wallet, monero_wallet_rpc_process))
} }
mod data { pub mod data {
use super::*; use super::*;
pub fn data_dir_from(arg_dir: Option<PathBuf>, testnet: bool) -> Result<PathBuf> { pub fn data_dir_from(arg_dir: Option<PathBuf>, testnet: bool) -> Result<PathBuf> {

View file

@ -1308,6 +1308,12 @@ pub struct CheckMoneroNodeResponse {
pub available: bool, pub available: bool,
} }
#[typeshare]
#[derive(Deserialize, Serialize)]
pub struct GetDataDirArgs {
pub is_testnet: bool,
}
#[derive(Error, Debug)] #[derive(Error, Debug)]
#[error("this is not one of the known monero networks")] #[error("this is not one of the known monero networks")]
struct UnknownMoneroNetwork(String); struct UnknownMoneroNetwork(String);