diff --git a/Cargo.lock b/Cargo.lock index 611e528..8673cbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2544,6 +2544,12 @@ dependencies = [ "serde", ] +[[package]] +name = "infer" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865e8a58ae8e24d2c4412c31344afa1d302a3740ad67528c10f50d6876cdcf55" + [[package]] name = "infer" version = "0.16.0" @@ -2954,6 +2960,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime-infer" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91caed19dd472bc88bcd063571df18153529d49301a1918f4cf37f42332bee2e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -4120,7 +4136,9 @@ dependencies = [ "anyhow", "axum", "base64 0.22.1", + "infer 0.3.7", "localtime", + "mime-infer", "radicle", "radicle-surf", "serde", @@ -5657,7 +5675,7 @@ dependencies = [ "glob", "html5ever", "http", - "infer", + "infer 0.16.0", "json-patch", "kuchikiki", "log", @@ -6357,6 +6375,12 @@ dependencies = [ "unic-common", ] +[[package]] +name = "unicase" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" + [[package]] name = "unicode-id-start" version = "1.0.4" diff --git a/crates/radicle-tauri/src/commands/cob.rs b/crates/radicle-tauri/src/commands/cob.rs index 29a4acf..642bf22 100644 --- a/crates/radicle-tauri/src/commands/cob.rs +++ b/crates/radicle-tauri/src/commands/cob.rs @@ -22,9 +22,10 @@ pub mod patch; pub async fn get_embed( ctx: tauri::State<'_, AppState>, rid: identity::RepoId, + name: Option, oid: git::Oid, -) -> Result, Error> { - ctx.get_embed(rid, oid) +) -> Result { + ctx.get_embed(rid, name, oid) } #[tauri::command] diff --git a/crates/radicle-types/Cargo.toml b/crates/radicle-types/Cargo.toml index b5223df..d9f1176 100644 --- a/crates/radicle-types/Cargo.toml +++ b/crates/radicle-types/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" anyhow = { version = "1.0.90" } axum = { version = "0.7.5", default-features = false, features = ["json"] } base64 = { version = "0.22.1" } +infer = { version = "0.3" } +mime-infer = { version = "3.0.0" } radicle = { version = "0.14.0", features = ["test"] } radicle-surf = { version = "0.22.1", features = ["serde"] } serde = { version = "1.0.210", features = ["derive"] } diff --git a/crates/radicle-types/bindings/cob/Embed.ts b/crates/radicle-types/bindings/cob/Embed.ts new file mode 100644 index 0000000..9b5d529 --- /dev/null +++ b/crates/radicle-types/bindings/cob/Embed.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type Embed = { content: Array; mimeType: string | null }; diff --git a/crates/radicle-types/bindings/cob/EmbedWithMimeType.ts b/crates/radicle-types/bindings/cob/EmbedWithMimeType.ts new file mode 100644 index 0000000..67a590f --- /dev/null +++ b/crates/radicle-types/bindings/cob/EmbedWithMimeType.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type EmbedWithMimeType = { + content: Array; + mimeType: string | null; +}; diff --git a/crates/radicle-types/src/cobs.rs b/crates/radicle-types/src/cobs.rs index 5549265..9cd539f 100644 --- a/crates/radicle-types/src/cobs.rs +++ b/crates/radicle-types/src/cobs.rs @@ -30,6 +30,15 @@ impl Author { } } +#[derive(Serialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +#[ts(export_to = "cob/")] +pub struct EmbedWithMimeType { + pub content: Vec, + pub mime_type: Option, +} + #[derive(TS, Serialize)] #[doc = "A type alias for the TS type `never`."] #[ts(export)] diff --git a/crates/radicle-types/src/traits/thread.rs b/crates/radicle-types/src/traits/thread.rs index 5c5eeda..53f71da 100644 --- a/crates/radicle-types/src/traits/thread.rs +++ b/crates/radicle-types/src/traits/thread.rs @@ -15,12 +15,31 @@ use crate::error::Error; use crate::traits::Profile; pub trait Thread: Profile { - fn get_embed(&self, rid: identity::RepoId, oid: git::Oid) -> Result, Error> { + fn get_embed( + &self, + rid: identity::RepoId, + name: Option, + oid: git::Oid, + ) -> Result { let profile = self.profile(); let repo = profile.storage.repository(rid)?; let blob = repo.blob(oid)?; + let content = blob.content(); + let mime_type = match infer::get(content).map(|i| i.mime_type().to_string()) { + Some(mime_type) => Some(mime_type), + None if name.is_some() => { + let filename = name.unwrap(); + mime_infer::from_path(&filename) + .first() + .map(|m| m.as_ref().to_string()) + } + _ => None, + }; - Ok::<_, Error>(blob.content().to_vec()) + Ok::<_, Error>(cobs::EmbedWithMimeType { + content: content.to_vec(), + mime_type, + }) } fn save_embed_to_disk( diff --git a/crates/test-http-api/src/api.rs b/crates/test-http-api/src/api.rs index c42e2e5..734b68f 100644 --- a/crates/test-http-api/src/api.rs +++ b/crates/test-http-api/src/api.rs @@ -244,14 +244,15 @@ async fn activity_handler( #[derive(Serialize, Deserialize)] struct EmbedBody { pub rid: identity::RepoId, + pub name: Option, pub oid: git::Oid, } async fn get_embeds_handler( State(ctx): State, - Json(EmbedBody { rid, oid }): Json, + Json(EmbedBody { rid, name, oid }): Json, ) -> impl IntoResponse { - let embed = ctx.get_embed(rid, oid)?; + let embed = ctx.get_embed(rid, name, oid)?; Ok::<_, Error>(Json(embed)) } diff --git a/src/components/Markdown.svelte b/src/components/Markdown.svelte index f4645b8..372e17e 100644 --- a/src/components/Markdown.svelte +++ b/src/components/Markdown.svelte @@ -1,4 +1,6 @@