Merge pull request #209 from Dvorinka/fix/thumb-obfuscated

fix(desktop): online-only Explorer thumbnails — tolerate missing obfuscated field (#167)
pull/3589/head
Tomáš Dvořák 2 weeks ago committed by GitHub
commit c02609515f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -231,6 +231,7 @@ Goal: Windows + macOS + Linux from the `desktop/` tree in this repo.
- Status: (1) notifications already per-OS (`win32_notif` / `notify_rust` / `mac_notification_sys`) — no abstraction needed; (2) hydration abstracted via `drive/placeholder` cfg swap — `cfapi` on Windows, `placeholder_non_windows` full-sync adapter elsewhere (FUSE / File Provider still open); (3) CI matrix builds + tests all 3 OSes; (4) packaging: `desktop-release.yml` on `desktop-v*` tags ships .msi/.exe (Windows), .dmg (macOS), .deb/.AppImage (Linux) — MSIX deferred (needs store signing).
- Verified on Linux: `cargo test --workspace` green (49 tests), `cargo tauri build` produces working .deb + .AppImage.
- Feature fallback on Linux/macOS until providers land: full sync without placeholders (download-on-access still works via sync engine).
- [x] #167 (upstream desktop#49) — online-only thumbnails missing in Explorer: root cause was a client/server contract mismatch — the CE `/file/thumb` response carries only `url`/`expires` while the `cloudreve-api` model required `obfuscated`, failing deserialization on every thumbnail request (`E_FAIL` to Explorer; hydrated files were unaffected since Windows thumbs them locally). `obfuscated` is now `#[serde(default)]`; the decode path still runs when a server emits the flag
## 7. Phase E — Android app (native, no iOS)

@ -254,6 +254,7 @@ pub struct FileThumbResponse {
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires: Option<String>,
#[serde(default)]
pub obfuscated: bool,
}
@ -575,3 +576,32 @@ pub enum FileEvent {
/// Batch of file events with data
Event(Vec<FileEventData>),
}
#[cfg(test)]
mod tests {
use super::FileThumbResponse;
#[test]
fn thumb_response_without_obfuscated_field_deserializes() {
// The CE server's /file/thumb response carries only `url`/`expires`;
// a missing `obfuscated` flag must not fail deserialization — otherwise
// every thumbnail request errors out and Explorer shows no thumbnails
// for online-only placeholders.
let res: FileThumbResponse =
serde_json::from_str(r#"{"url":"https://example.com/t.jpg","expires":null}"#)
.expect("response without `obfuscated` must deserialize");
assert!(!res.obfuscated);
assert_eq!(res.url, "https://example.com/t.jpg");
assert!(res.expires.is_none());
}
#[test]
fn thumb_response_with_obfuscated_field_deserializes() {
let res: FileThumbResponse = serde_json::from_str(
r#"{"url":"abc","expires":"2026-01-01T00:00:00Z","obfuscated":true}"#,
)
.expect("response with `obfuscated` must deserialize");
assert!(res.obfuscated);
assert_eq!(res.expires.as_deref(), Some("2026-01-01T00:00:00Z"));
}
}

Loading…
Cancel
Save