backend: split assets into objects
This commit is contained in:
@@ -172,7 +172,7 @@ class AssetManager {
|
||||
return next;
|
||||
}
|
||||
|
||||
ensureAsset(documentId, asset, { force = false } = {}) {
|
||||
ensureAsset(documentId, asset, { force = false, start = null, limit = null } = {}) {
|
||||
if (!documentId || !asset?.id) {
|
||||
return Promise.resolve(asset || null);
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class AssetManager {
|
||||
return Promise.resolve({ ...asset, ...cached });
|
||||
}
|
||||
|
||||
const inflightKey = `${documentId}:${asset.id}`;
|
||||
const inflightKey = `${documentId}:${asset.id}:${start ?? 'd'}:${limit ?? 'd'}`;
|
||||
if (!force && this.assetInflight.has(inflightKey)) {
|
||||
return this.assetInflight.get(inflightKey);
|
||||
}
|
||||
@@ -198,13 +198,31 @@ class AssetManager {
|
||||
return Promise.reject(new Error('AssetManager API client is not configured.'));
|
||||
}
|
||||
|
||||
const params = {};
|
||||
if (Number.isInteger(start) && start > 0) {
|
||||
params.start = start;
|
||||
}
|
||||
if (Number.isInteger(limit) && limit > 0) {
|
||||
params.limit = limit;
|
||||
}
|
||||
|
||||
const requestConfig = Object.keys(params).length ? { params } : undefined;
|
||||
|
||||
const request = this.api
|
||||
.get(`/documents/${documentId}/assets/${asset.id}`)
|
||||
.get(`/assets/${asset.id}`, requestConfig)
|
||||
.then(({ data }) => {
|
||||
const objects = Array.isArray(data.objects) ? data.objects : [];
|
||||
const primaryObject = objects[0] || null;
|
||||
const expiresAt = typeof primaryObject?.expires_at === 'number'
|
||||
? primaryObject.expires_at
|
||||
: Date.now() + this.assetPresignTtlMs;
|
||||
|
||||
const entry = {
|
||||
...asset,
|
||||
...data,
|
||||
expiresAt: Date.now() + this.assetPresignTtlMs,
|
||||
objects,
|
||||
url: primaryObject?.url || null,
|
||||
expiresAt,
|
||||
};
|
||||
this.rememberAsset(entry);
|
||||
return entry;
|
||||
|
||||
@@ -446,8 +446,10 @@ const DetailPanel = ({
|
||||
return null;
|
||||
}
|
||||
const asset = getDocumentAsset(doc, 'preview');
|
||||
const width = Number(asset?.metadata?.width) || 0;
|
||||
const height = Number(asset?.metadata?.height) || 0;
|
||||
const primaryObject = asset?.objects?.[0] || null;
|
||||
const primaryMetadata = primaryObject?.metadata || asset?.metadata || {};
|
||||
const width = Number(primaryMetadata?.width) || 0;
|
||||
const height = Number(primaryMetadata?.height) || 0;
|
||||
const orientation = width > 0 && height > 0 ? (width >= height ? 'landscape' : 'portrait') : 'landscape';
|
||||
return {
|
||||
id: doc.id,
|
||||
|
||||
@@ -22,8 +22,10 @@ const DocumentThumbnailImage = ({
|
||||
}) => {
|
||||
const resolvedMaxSize = Math.max(1, Math.round(maxSize || 1));
|
||||
const thumbnailAsset = useMemo(() => getAssetFromVersion(document?.current_version, 'thumbnail'), [document?.current_version]);
|
||||
const assetWidth = Number(thumbnailAsset?.metadata?.width);
|
||||
const assetHeight = Number(thumbnailAsset?.metadata?.height);
|
||||
const primaryObject = thumbnailAsset?.objects?.[0] || null;
|
||||
const primaryMetadata = primaryObject?.metadata || thumbnailAsset?.metadata || {};
|
||||
const assetWidth = Number(primaryMetadata?.width);
|
||||
const assetHeight = Number(primaryMetadata?.height);
|
||||
|
||||
const dimensions = useMemo(() => {
|
||||
if (!Number.isFinite(assetWidth) || assetWidth <= 0 || !Number.isFinite(assetHeight) || assetHeight <= 0) {
|
||||
|
||||
@@ -413,11 +413,13 @@ const AppLayout = () => {
|
||||
|
||||
const isAssetEquivalent = (lhs, rhs) => {
|
||||
if (!lhs || !rhs) return false;
|
||||
const lhsPrimaryMetadata = lhs?.objects?.[0]?.metadata || lhs?.metadata;
|
||||
const rhsPrimaryMetadata = rhs?.objects?.[0]?.metadata || rhs?.metadata;
|
||||
return (
|
||||
lhs.id === rhs.id &&
|
||||
lhs.url === rhs.url &&
|
||||
lhs?.metadata?.width === rhs?.metadata?.width &&
|
||||
lhs?.metadata?.height === rhs?.metadata?.height &&
|
||||
lhsPrimaryMetadata?.width === rhsPrimaryMetadata?.width &&
|
||||
lhsPrimaryMetadata?.height === rhsPrimaryMetadata?.height &&
|
||||
lhs.mime_type === rhs.mime_type &&
|
||||
lhs.asset_type === rhs.asset_type &&
|
||||
lhs.created_at === rhs.created_at
|
||||
|
||||
@@ -502,8 +502,10 @@ const SkeuomorphicWorkspace = ({
|
||||
(doc) => {
|
||||
if (!doc) return null;
|
||||
const asset = resolvePreviewAsset(doc);
|
||||
const width = asset?.metadata?.width;
|
||||
const height = asset?.metadata?.height;
|
||||
const primaryObject = asset?.objects?.[0] || null;
|
||||
const primaryMetadata = primaryObject?.metadata || asset?.metadata || {};
|
||||
const width = primaryMetadata?.width;
|
||||
const height = primaryMetadata?.height;
|
||||
if (typeof width === 'number' && typeof height === 'number') {
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
@@ -751,7 +751,6 @@ button.icon-button.ghost:hover:not([disabled]) {
|
||||
}
|
||||
|
||||
.column + .column {
|
||||
border-left: none;
|
||||
padding-left: 1.25rem;
|
||||
}
|
||||
|
||||
@@ -847,7 +846,6 @@ button.icon-button.ghost:hover:not([disabled]) {
|
||||
color: inherit;
|
||||
transition: background 0.12s ease, color 0.12s ease;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.folder-row span.name {
|
||||
@@ -1511,6 +1509,7 @@ button.icon-button.ghost:hover:not([disabled]) {
|
||||
position: relative;
|
||||
padding: 1.25rem;
|
||||
overflow-y: auto;
|
||||
border-left: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.detail-panel .column-body {
|
||||
|
||||
Reference in New Issue
Block a user