assets
This commit is contained in:
@@ -77,6 +77,20 @@ impl From<Tag> for TagResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Default)]
|
||||
pub struct DocumentAssetGroupResponse {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail: Option<DocumentAssetResponse>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub preview: Option<DocumentAssetResponse>,
|
||||
}
|
||||
|
||||
impl DocumentAssetGroupResponse {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.thumbnail.is_none() && self.preview.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DocumentResponse {
|
||||
pub id: Uuid,
|
||||
@@ -92,8 +106,8 @@ pub struct DocumentResponse {
|
||||
pub issued_at: Option<String>,
|
||||
pub metadata: Value,
|
||||
pub tags: Vec<TagResponse>,
|
||||
pub thumbnail: Option<DocumentAssetResponse>,
|
||||
pub preview: Option<DocumentAssetResponse>,
|
||||
#[serde(default, skip_serializing_if = "DocumentAssetGroupResponse::is_empty")]
|
||||
pub assets: DocumentAssetGroupResponse,
|
||||
pub download_path: String,
|
||||
}
|
||||
|
||||
@@ -119,11 +133,7 @@ pub struct DocumentAssetResponse {
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PrimaryDocumentAssets {
|
||||
pub thumbnail: Option<DocumentAssetResponse>,
|
||||
pub preview: Option<DocumentAssetResponse>,
|
||||
}
|
||||
type PrimaryDocumentAssets = DocumentAssetGroupResponse;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DocumentDetailResponse {
|
||||
@@ -251,18 +261,13 @@ pub async fn list_documents(
|
||||
let mut response = Vec::with_capacity(doc_ids.len());
|
||||
for doc in docs {
|
||||
let tags = tags_map.get(&doc.id).cloned();
|
||||
let (thumbnail, preview) = if let Some(assets) = primary_assets.get(&doc.id) {
|
||||
(assets.thumbnail.clone(), assets.preview.clone())
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let assets = primary_assets.get(&doc.id).cloned();
|
||||
response.push(to_document_response(
|
||||
&state,
|
||||
user.user_id,
|
||||
doc,
|
||||
tags,
|
||||
thumbnail,
|
||||
preview,
|
||||
assets,
|
||||
)?);
|
||||
}
|
||||
|
||||
@@ -291,14 +296,21 @@ pub async fn get_document(
|
||||
drop(conn);
|
||||
|
||||
let assets = load_asset_responses(&state, version_id).await?;
|
||||
let thumbnail = assets
|
||||
let mut grouped_assets = DocumentAssetGroupResponse::default();
|
||||
if let Some(asset) = assets
|
||||
.iter()
|
||||
.find(|asset| asset.asset_type == "thumbnail")
|
||||
.cloned();
|
||||
let preview = assets
|
||||
.cloned()
|
||||
{
|
||||
grouped_assets.thumbnail = Some(asset);
|
||||
}
|
||||
if let Some(asset) = assets
|
||||
.iter()
|
||||
.find(|asset| asset.asset_type == "preview")
|
||||
.cloned();
|
||||
.cloned()
|
||||
{
|
||||
grouped_assets.preview = Some(asset);
|
||||
}
|
||||
|
||||
Ok(Json(DocumentDetailResponse {
|
||||
document: to_document_response(
|
||||
@@ -306,8 +318,7 @@ pub async fn get_document(
|
||||
user.user_id,
|
||||
doc,
|
||||
tags_map.get(&document_id).cloned(),
|
||||
thumbnail,
|
||||
preview,
|
||||
Some(grouped_assets),
|
||||
)?,
|
||||
current_version: to_version_response(current_version),
|
||||
assets,
|
||||
@@ -695,14 +706,21 @@ pub async fn update_document(
|
||||
drop(conn);
|
||||
|
||||
let assets = load_asset_responses(&state, version_id).await?;
|
||||
let thumbnail = assets
|
||||
let mut grouped_assets = DocumentAssetGroupResponse::default();
|
||||
if let Some(asset) = assets
|
||||
.iter()
|
||||
.find(|asset| asset.asset_type == "thumbnail")
|
||||
.cloned();
|
||||
let preview = assets
|
||||
.cloned()
|
||||
{
|
||||
grouped_assets.thumbnail = Some(asset);
|
||||
}
|
||||
if let Some(asset) = assets
|
||||
.iter()
|
||||
.find(|asset| asset.asset_type == "preview")
|
||||
.cloned();
|
||||
.cloned()
|
||||
{
|
||||
grouped_assets.preview = Some(asset);
|
||||
}
|
||||
|
||||
Ok(Json(DocumentDetailResponse {
|
||||
document: to_document_response(
|
||||
@@ -710,8 +728,7 @@ pub async fn update_document(
|
||||
user.user_id,
|
||||
document,
|
||||
tags_map.get(&document_id).cloned(),
|
||||
thumbnail,
|
||||
preview,
|
||||
Some(grouped_assets),
|
||||
)?,
|
||||
current_version: to_version_response(current_version),
|
||||
assets,
|
||||
@@ -991,14 +1008,21 @@ async fn process_upload(
|
||||
let tags = tags_map.get(&document.id).cloned();
|
||||
drop(conn);
|
||||
let assets = load_asset_responses(state, version.id).await?;
|
||||
let thumbnail = assets
|
||||
let mut grouped_assets = DocumentAssetGroupResponse::default();
|
||||
if let Some(asset) = assets
|
||||
.iter()
|
||||
.find(|asset| asset.asset_type == "thumbnail")
|
||||
.cloned();
|
||||
let preview = assets
|
||||
.cloned()
|
||||
{
|
||||
grouped_assets.thumbnail = Some(asset);
|
||||
}
|
||||
if let Some(asset) = assets
|
||||
.iter()
|
||||
.find(|asset| asset.asset_type == "preview")
|
||||
.cloned();
|
||||
.cloned()
|
||||
{
|
||||
grouped_assets.preview = Some(asset);
|
||||
}
|
||||
|
||||
info!(
|
||||
document_id = %document.id,
|
||||
@@ -1009,7 +1033,11 @@ async fn process_upload(
|
||||
return Ok(UploadOutcome {
|
||||
detail: DocumentDetailResponse {
|
||||
document: to_document_response(
|
||||
state, user_id, document, tags, thumbnail, preview,
|
||||
state,
|
||||
user_id,
|
||||
document,
|
||||
tags,
|
||||
Some(grouped_assets),
|
||||
)?,
|
||||
current_version: to_version_response(version),
|
||||
assets,
|
||||
@@ -1081,7 +1109,7 @@ async fn process_upload(
|
||||
};
|
||||
|
||||
let detail = DocumentDetailResponse {
|
||||
document: to_document_response(state, user_id, document, None, None, None)?,
|
||||
document: to_document_response(state, user_id, document, None, None)?,
|
||||
current_version: to_version_response(version.clone()),
|
||||
assets: Vec::new(),
|
||||
};
|
||||
@@ -1255,8 +1283,7 @@ pub(crate) fn to_document_response(
|
||||
user_id: Uuid,
|
||||
doc: Document,
|
||||
tags: Option<Vec<Tag>>,
|
||||
thumbnail: Option<DocumentAssetResponse>,
|
||||
preview: Option<DocumentAssetResponse>,
|
||||
assets: Option<DocumentAssetGroupResponse>,
|
||||
) -> AppResult<DocumentResponse> {
|
||||
let download_path = build_download_path(state, doc.id, user_id)?;
|
||||
|
||||
@@ -1278,8 +1305,7 @@ pub(crate) fn to_document_response(
|
||||
.into_iter()
|
||||
.map(TagResponse::from)
|
||||
.collect(),
|
||||
thumbnail,
|
||||
preview,
|
||||
assets: assets.unwrap_or_default(),
|
||||
download_path,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -220,18 +220,13 @@ pub async fn list_folder_contents(
|
||||
let mut documents = Vec::with_capacity(doc_ids.len());
|
||||
for doc in docs {
|
||||
let tags = tags_map.get(&doc.id).cloned();
|
||||
let (thumbnail, preview) = if let Some(assets) = primary_assets.get(&doc.id) {
|
||||
(assets.thumbnail.clone(), assets.preview.clone())
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let assets = primary_assets.get(&doc.id).cloned();
|
||||
documents.push(to_document_response(
|
||||
&state,
|
||||
user.user_id,
|
||||
doc,
|
||||
tags,
|
||||
thumbnail,
|
||||
preview,
|
||||
assets,
|
||||
)?);
|
||||
}
|
||||
|
||||
@@ -408,18 +403,13 @@ pub async fn search_documents(
|
||||
let mut response = Vec::with_capacity(doc_ids.len());
|
||||
for doc in docs {
|
||||
let tags = tags_map.get(&doc.id).cloned();
|
||||
let (thumbnail, preview) = if let Some(assets) = primary_assets.get(&doc.id) {
|
||||
(assets.thumbnail.clone(), assets.preview.clone())
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let assets = primary_assets.get(&doc.id).cloned();
|
||||
response.push(to_document_response(
|
||||
&state,
|
||||
user.user_id,
|
||||
doc,
|
||||
tags,
|
||||
thumbnail,
|
||||
preview,
|
||||
assets,
|
||||
)?);
|
||||
}
|
||||
|
||||
|
||||
+13
-6
@@ -731,6 +731,8 @@ const DocumentsTable = ({
|
||||
rowClasses.push('dragging');
|
||||
}
|
||||
|
||||
const thumbnailAsset = doc?.assets?.thumbnail || null;
|
||||
|
||||
return (
|
||||
<tr
|
||||
key={doc.id}
|
||||
@@ -753,9 +755,9 @@ const DocumentsTable = ({
|
||||
onDragEnd={onDocumentDragEnd}
|
||||
>
|
||||
<td className="thumb-cell">
|
||||
{doc.thumbnail ? (
|
||||
{thumbnailAsset ? (
|
||||
<img
|
||||
src={doc.thumbnail.url}
|
||||
src={thumbnailAsset.url}
|
||||
alt={`Thumbnail for ${doc.title || doc.original_name}`}
|
||||
className="document-thumbnail"
|
||||
/>
|
||||
@@ -1029,11 +1031,16 @@ const DetailPanel = ({
|
||||
|
||||
const makePreviewItem = useCallback((doc, detailEntry, fallbackUrl = null) => {
|
||||
if (!doc) return null;
|
||||
const url = doc.thumbnail?.url || detailEntry?.document?.thumbnail?.url || fallbackUrl;
|
||||
const detailDocument = detailEntry?.document || null;
|
||||
const thumbnailAsset =
|
||||
doc?.assets?.thumbnail ||
|
||||
detailDocument?.assets?.thumbnail ||
|
||||
detailEntry?.assets?.find((item) => item.asset_type === 'thumbnail') ||
|
||||
null;
|
||||
const url = thumbnailAsset?.url || fallbackUrl;
|
||||
if (!url) return null;
|
||||
const asset = detailEntry?.assets?.find((item) => item.asset_type === 'thumbnail');
|
||||
const width = asset?.width || 0;
|
||||
const height = asset?.height || 0;
|
||||
const width = thumbnailAsset?.width || 0;
|
||||
const height = thumbnailAsset?.height || 0;
|
||||
const orientation = width > 0 && height > 0 ? (width >= height ? 'landscape' : 'portrait') : 'landscape';
|
||||
return {
|
||||
id: doc.id,
|
||||
|
||||
Reference in New Issue
Block a user