feat: responsive pause/stop, non-blocking update with progress bar, delete saved sessions (1.5.0)
CI / Format and clippy (push) Successful in 25s
Release / Create release (push) Successful in 13s
CI / Dependency audit (push) Successful in 11s
CI / Check desktop app (Linux) (push) Successful in 1m35s
Release / CLI (linux-x86_64) (push) Successful in 2m31s
Release / CLI (linux-aarch64) (push) Successful in 1m46s
CI / Tests (Linux) (push) Successful in 4m28s
Release / Desktop app (linux-x86_64) (push) Successful in 6m9s
Release / Desktop app (windows) (push) Successful in 4m13s
Release / Desktop app (linux-aarch64) (push) Successful in 9m51s

- carve: check cancellation inside chunks and per hit; reassembly stage is cancellable
- status exposes `stopping`; UI shows "Pausing…" immediately
- Tauri update commands run off the UI thread; download percentage reported
- delete autosaved sessions manually (one/all) and by retention setting
- chore(release): 1.5.0

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-11-03 16:36:34 -03:00
1 parent db5b972650
commit 0b9a16e8a0
20 files changed
+262 -35

No files matched your search

+2 -2
View File
@@ -1342,7 +1342,7 @@ dependencies = [
[[package]]
name = "guara-core"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"aes",
"argon2",
@@ -1373,7 +1373,7 @@ dependencies = [
[[package]]
name = "guara-gui"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"guara-core",
"libc",
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "guara-gui"
description = "Guará: graphical file recovery interface"
version = "1.4.0"
version = "1.5.0"
edition = "2021"
license = "MIT OR Apache-2.0"
authors = ["Guará contributors"]
+24 -8
View File
@@ -22,25 +22,41 @@ async fn rpc(
}
#[tauri::command]
fn update_check(state: tauri::State<'_, State>) -> Result<serde_json::Value, String> {
let status = state.0.update_check().map_err(|e| e.to_string())?;
serde_json::to_value(status).map_err(|e| e.to_string())
async fn update_check(state: tauri::State<'_, State>) -> Result<serde_json::Value, String> {
let eng = state.0.clone();
tauri::async_runtime::spawn_blocking(move || {
let status = eng.update_check().map_err(|e| e.to_string())?;
serde_json::to_value(status).map_err(|e| e.to_string())
})
.await
.map_err(|e| e.to_string())?
}
#[tauri::command]
fn update_apply(app: tauri::AppHandle, state: tauri::State<'_, State>) -> Result<String, String> {
async fn update_apply(app: tauri::AppHandle, state: tauri::State<'_, State>) -> Result<String, String> {
use tauri::Emitter;
#[cfg(any(target_os = "linux", target_os = "macos"))]
let exe = elevated_exe().unwrap_or_else(|_| std::env::current_exe().unwrap_or_default());
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
let exe = std::env::current_exe().unwrap_or_default();
state
.0
.update_apply_desktop(&exe, move |phase| {
let _ = app.emit("update-progress", serde_json::json!({ "phase": phase }));
// Blocking download/install must not run on the UI thread, or the window freezes.
let eng = state.0.clone();
tauri::async_runtime::spawn_blocking(move || {
eng.update_apply_desktop(&exe, move |phase| {
let (name, pct) = match phase.split_once(':') {
Some((n, p)) => (n, p.parse::<u8>().ok()),
None => (phase, None),
};
let _ = app.emit(
"update-progress",
serde_json::json!({ "phase": name, "percent": pct }),
);
})
.map_err(|e| e.to_string())
})
.await
.map_err(|e| e.to_string())?
}
/// `true` when the process already has sufficient privileges to read raw disks.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Guará",
"version": "1.4.0",
"version": "1.5.0",
"identifier": "dev.guara.app",
"build": {
"frontendDist": "../ui"