Radish alpha
r
Radicle desktop app
Radicle
Git (anonymous pull)
Log in to clone via SSH
Use a save-as dialog for blob artifact downloads
Daniel Norman committed 7 days ago
commit b25722e9b0d10217ac668b1ee79c0a36406004f7
parent 859e5bff2090c102a1783e9a51a102236f739ce5
3 files changed +25 -9
modified crates/radicle-tauri/src/commands/cob/release.rs
@@ -337,6 +337,27 @@ pub async fn pick_artifact_directory(app: tauri::AppHandle) -> Result<Option<Str
        .map(|p| p.to_string_lossy().into_owned()))
}

+
/// Open the OS "Save as" dialog seeded with `suggested_name`. Returns the
+
/// path the user picked, or `None` if they cancelled. The frontend feeds
+
/// the path into `download_artifact` as the destination for a Blob fetch.
+
#[tauri::command]
+
pub async fn pick_artifact_save_path(
+
    app: tauri::AppHandle,
+
    suggested_name: String,
+
) -> Result<Option<String>, Error> {
+
    let (tx, rx) = tokio::sync::oneshot::channel();
+
    app.dialog()
+
        .file()
+
        .set_file_name(suggested_name)
+
        .save_file(move |path| {
+
            let _ = tx.send(path);
+
        });
+
    let path = rx.await.map_err(|_| Error::DialogClosed)?;
+
    Ok(path
+
        .and_then(|p| p.into_path().ok())
+
        .map(|p| p.to_string_lossy().into_owned()))
+
}
+

// Settings ------------------------------------------------------------------

#[tauri::command]
modified crates/radicle-tauri/src/lib.rs
@@ -63,6 +63,7 @@ pub fn run() {
            cob::release::download_artifact,
            cob::release::pick_artifact_files,
            cob::release::pick_artifact_directory,
+
            cob::release::pick_artifact_save_path,
            cob::release::get_auto_seed_artifacts,
            cob::release::set_auto_seed_artifacts,
            cob::save_embed_by_bytes,
modified src/views/repo/Release.svelte
@@ -194,7 +194,9 @@
    const isCollection = artifact.kind === "collection";
    const dest = isCollection
      ? await invoke<string | null>("pick_artifact_directory")
-
      : await pickSaveFile(artifact.name);
+
      : await invoke<string | null>("pick_artifact_save_path", {
+
          suggestedName: artifact.name,
+
        });
    if (!dest) return;

    busy[artifact.cid] = true;
@@ -294,14 +296,6 @@
    }
  }

-
  // Tauri's dialog plugin offers a save_file picker, but exposing it would
-
  // be a new IPC surface. Reuse the existing pick_artifact_files command —
-
  // it works as a "pick a destination" prompt on macOS / Linux today.
-
  async function pickSaveFile(_suggestedName: string): Promise<string | null> {
-
    const files = await invoke<string[]>("pick_artifact_files");
-
    return files[0] ?? null;
-
  }
-

  function formatTimestamp(ts: number): string {
    return new Date(ts * 1000).toLocaleString();
  }