fix(call): Response return-type can't be wrapped in Result
Previous commit had the command typed as Result<tauri::ipc::Response, String>. Turns out that forces Tauri to JSON-serialise the variant wrapper around the Response body — the frontend gets a JSON object instead of the raw ArrayBuffer, the runtime check for byteLength fails, and every thumbnail comes back as null. Changed the return type to `tauri::ipc::Response` directly. Bad source ids and capture failures now funnel into an empty byte buffer; the JS side still detects "no thumbnail" via `byteLength === 0` so the contract stays the same. Frontend also widens the invoke-result typing to ArrayBuffer | Uint8Array | number[] so an older WebView2 that happens to deserialise as an array still works, and normalises into a plain ArrayBuffer before constructing the Blob to sidestep a TS SharedArrayBuffer incompatibility. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -83,22 +83,23 @@ pub fn capture_screen_source_thumbnail(source_id: String) -> Result<Option<Strin
|
||||
// expose via `URL.createObjectURL` — skips the base64-decode step
|
||||
// entirely and keeps the main thread responsive during fan-in.
|
||||
//
|
||||
// A capture failure (source vanished, permission denied) returns an empty
|
||||
// byte buffer rather than an error so the JS side gets a uniform contract
|
||||
// (ArrayBuffer always). Caller checks `byteLength === 0` to detect the
|
||||
// no-thumbnail case.
|
||||
// The return type MUST be `Response` directly (not `Result<Response, E>`):
|
||||
// a Result wrapper forces Tauri to JSON-serialise the variant so the
|
||||
// frontend gets a JSON object instead of raw bytes. Failures — bad id
|
||||
// format, capture errors, source vanished — all funnel into an empty
|
||||
// byte buffer; the caller treats `byteLength === 0` as the "no thumbnail"
|
||||
// signal.
|
||||
#[tauri::command]
|
||||
pub fn capture_screen_source_thumbnail_bytes(
|
||||
source_id: String,
|
||||
) -> Result<tauri::ipc::Response, String> {
|
||||
pub fn capture_screen_source_thumbnail_bytes(source_id: String) -> tauri::ipc::Response {
|
||||
let bytes = if let Some(raw) = source_id.strip_prefix("screen:").and_then(strip_zero_suffix) {
|
||||
capture_monitor_bytes_by_id(raw).unwrap_or_default()
|
||||
} else if let Some(raw) = source_id.strip_prefix("window:").and_then(strip_zero_suffix) {
|
||||
capture_window_bytes_by_id(raw).unwrap_or_default()
|
||||
} else {
|
||||
return Err(format!("unknown source id format: {source_id}"));
|
||||
eprintln!("capture_screen_source_thumbnail_bytes: unknown id format: {source_id}");
|
||||
Vec::new()
|
||||
};
|
||||
Ok(tauri::ipc::Response::new(bytes))
|
||||
tauri::ipc::Response::new(bytes)
|
||||
}
|
||||
|
||||
fn strip_zero_suffix(s: &str) -> Option<&str> {
|
||||
|
||||
Reference in New Issue
Block a user