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