mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-09 13:40:28 +08:00
Infer file type for embeds for previews
This commit is contained in:
Generated
+25
-1
@@ -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",
|
||||
@@ -5659,7 +5677,7 @@ dependencies = [
|
||||
"glob",
|
||||
"html5ever",
|
||||
"http",
|
||||
"infer",
|
||||
"infer 0.16.0",
|
||||
"json-patch",
|
||||
"kuchikiki",
|
||||
"log",
|
||||
@@ -6379,6 +6397,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"
|
||||
|
||||
@@ -22,9 +22,10 @@ pub mod patch;
|
||||
pub async fn get_embed(
|
||||
ctx: tauri::State<'_, AppState>,
|
||||
rid: identity::RepoId,
|
||||
name: Option<String>,
|
||||
oid: git::Oid,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
ctx.get_embed(rid, oid)
|
||||
) -> Result<types::cobs::EmbedWithMimeType, Error> {
|
||||
ctx.get_embed(rid, name, oid)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -8,6 +8,8 @@ anyhow = { version = "1.0.90" }
|
||||
axum = { version = "0.7.5", default-features = false, features = ["json"] }
|
||||
base64 = { version = "0.22.1" }
|
||||
localtime = { version = "1.3.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"] }
|
||||
|
||||
@@ -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<number>; mimeType: string | null };
|
||||
@@ -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<number>;
|
||||
mimeType: string | null;
|
||||
};
|
||||
@@ -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<u8>,
|
||||
pub mime_type: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(TS, Serialize)]
|
||||
#[doc = "A type alias for the TS type `never`."]
|
||||
#[ts(export)]
|
||||
|
||||
@@ -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<Vec<u8>, Error> {
|
||||
fn get_embed(
|
||||
&self,
|
||||
rid: identity::RepoId,
|
||||
name: Option<String>,
|
||||
oid: git::Oid,
|
||||
) -> Result<cobs::EmbedWithMimeType, Error> {
|
||||
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(
|
||||
|
||||
@@ -244,14 +244,15 @@ async fn activity_handler(
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct EmbedBody {
|
||||
pub rid: identity::RepoId,
|
||||
pub name: Option<String>,
|
||||
pub oid: git::Oid,
|
||||
}
|
||||
|
||||
async fn get_embeds_handler(
|
||||
State(ctx): State<Context>,
|
||||
Json(EmbedBody { rid, oid }): Json<EmbedBody>,
|
||||
Json(EmbedBody { rid, name, oid }): Json<EmbedBody>,
|
||||
) -> impl IntoResponse {
|
||||
let embed = ctx.get_embed(rid, oid)?;
|
||||
let embed = ctx.get_embed(rid, name, oid)?;
|
||||
|
||||
Ok::<_, Error>(Json(embed))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { Embed } from "@bindings/cob/Embed";
|
||||
|
||||
import dompurify from "dompurify";
|
||||
import matter from "@radicle/gray-matter";
|
||||
import { toDom } from "hast-util-to-dom";
|
||||
@@ -68,7 +70,6 @@
|
||||
|
||||
// If the markdown link is an oid embed
|
||||
if (href && isCommit(href)) {
|
||||
e.style.display = "block";
|
||||
e.onclick = event => {
|
||||
event.preventDefault();
|
||||
invoke("save_embed_to_disk", {
|
||||
@@ -77,47 +78,51 @@
|
||||
name: e.innerText,
|
||||
}).catch(console.error);
|
||||
};
|
||||
void invoke<Uint8Array>("get_embed", {
|
||||
void invoke<Embed>("get_embed", {
|
||||
rid,
|
||||
name: e.innerText,
|
||||
oid: href,
|
||||
})
|
||||
.then(byteArray => {
|
||||
const buffer = Buffer.from(byteArray);
|
||||
.then(({ mimeType, content }) => {
|
||||
const buffer = Buffer.from(content);
|
||||
const blob = new Blob([buffer]);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const ext = e.innerHTML.split(".").at(-1);
|
||||
// Embed an img element below the link
|
||||
if (ext?.match(/(gif|jpe?g|tiff?|png|webp|bmp)/)) {
|
||||
if (mimeType?.startsWith("image")) {
|
||||
const element = document.createElement("img");
|
||||
element.setAttribute("src", url);
|
||||
element.style.display = "block";
|
||||
e.style.display = "block";
|
||||
e.insertAdjacentElement("afterend", element);
|
||||
// Embed an iframe to display pdf correctly element below the link
|
||||
} else if (ext?.match(/(pdf)/)) {
|
||||
} else if (mimeType?.startsWith("application")) {
|
||||
const element = document.createElement("embed");
|
||||
element.setAttribute("src", url);
|
||||
element.type = "application/pdf";
|
||||
element.type = mimeType;
|
||||
element.style.overflow = "scroll";
|
||||
element.style.height = "40rem";
|
||||
element.style.overscrollBehavior = "contain";
|
||||
e.style.display = "block";
|
||||
e.insertAdjacentElement("afterend", element);
|
||||
} else if (ext?.match(/(mp4|mov)/)) {
|
||||
} else if (mimeType?.startsWith("video")) {
|
||||
const element = document.createElement("video");
|
||||
const node = document.createElement("source");
|
||||
node.src = url;
|
||||
element.controls = true;
|
||||
node.type = `video/mp4`;
|
||||
node.type = mimeType;
|
||||
element.style.width = "100%";
|
||||
e.style.display = "block";
|
||||
element.appendChild(node);
|
||||
e.insertAdjacentElement("afterend", element);
|
||||
} else if (ext?.match(/(mp3)/)) {
|
||||
} else if (mimeType?.startsWith("audio")) {
|
||||
const element = document.createElement("audio");
|
||||
element.style.display = "block";
|
||||
element.src = url;
|
||||
element.controls = true;
|
||||
e.style.display = "block";
|
||||
e.insertAdjacentElement("afterend", element);
|
||||
} else {
|
||||
console.warn(
|
||||
`Not able to provide a preview for ${e.innerHTML}`,
|
||||
);
|
||||
console.warn(`Not able to provide a preview for this file.`);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
Reference in New Issue
Block a user