Share a card's image from the preview

A share button beside the preview's close button sends the face being
shown at Scryfall's large size: on desktop the image is decoded and put on
the clipboard (tauri-plugin-clipboard-manager); on Android it's saved to
the cache and handed to the system share sheet by a small in-repo plugin
(SharePlugin.kt) through the app's FileProvider. The preview's corner
buttons are also a little larger.
This commit is contained in:
2026-10-24 15:20:27 -05:00
parent 7415289257
commit 226878fdd7
10 changed files with 597 additions and 5 deletions

View File

@@ -51,3 +51,24 @@ pub(crate) fn get_json<T: serde::de::DeserializeOwned>(url: &str) -> Result<T> {
.call()?
.into_json()?)
}
/// Most bytes [`fetch_image`] will read. Scryfall's largest card scans are a
/// few hundred kilobytes; this only stops a bad URL streaming forever.
const MAX_IMAGE_BYTES: u64 = 20 << 20;
/// GET a card image (a Scryfall scan) as bytes, for sharing or copying it.
/// HTTPS only.
pub fn fetch_image(url: &str) -> Result<Vec<u8>> {
if !url.starts_with("https://") {
return Err(crate::error::CoreError::Other(format!("not an https image URL: {url}")));
}
let mut bytes = Vec::new();
agent()
.get(url)
.set("User-Agent", USER_AGENT)
.call()?
.into_reader()
.take(MAX_IMAGE_BYTES)
.read_to_end(&mut bytes)?;
Ok(bytes)
}

View File

@@ -28,6 +28,7 @@ use std::path::Path;
use rusqlite::Connection;
pub use error::{CoreError, Result};
pub use http::fetch_image;
pub use model::{
CardRef, ColorSet, Deck, DeckEntry, LegalStatus, Legalities, LibraryCard, LibraryCopy,
LibraryFacets, LibraryFilter, LibraryStats, PrintingRef,