import { handleDelete, handleFetch, stringifyQuery } from './helpers'; import { Asset, AssetSortField, AssetSortOrder, AssetTypeFilter, AssetVariant, SearchResponse } from '../types/api'; // source & more icons: https://www.iconfinder.com/icons/774684/document_extension_file_format_pdf_icon import pdfImage from '../images/pdf.png'; import mp4Image from '../images/mp4.png'; import zipImage from '../images/zip.png'; import webmImage from '../images/webm.png'; const ITEMS_PER_PAGE = 50; export interface AssetSearchPayload { query?: string; page?: number; assetTypeFilter?: AssetTypeFilter; assetSortField?: AssetSortField; assetSortOrder?: AssetSortOrder; tagFilter?: string[]; timestamp?: number; } export default class AssetApi { public static async search(payload: AssetSearchPayload): Promise { const body = JSON.stringify({ ...payload, itemsPerPage: ITEMS_PER_PAGE, partialMatch: true }); const response = await handleFetch(`/assets/search`, { method: 'post', body: body }); return response.json(); } public static async getAssetById(id: string): Promise { const response = await handleFetch(`/assets/${id}`); // case: empty Guid as id if (response.status === 204) { return null; } return response.json(); } public static async updateAsset(asset: Asset): Promise { const response = await handleFetch(`/assets/${asset.id}/update`, { method: 'put', body: JSON.stringify(asset) }); return response.json(); } public static async createAsset(data: FormData): Promise { const response = await handleFetch( '/assets/create', { method: 'post', body: data }, false ); return response.json(); } public static async deleteAsset(id: string): Promise { const response = await handleDelete(`/assets/${id}/delete`); return response; } public static async createPublicAssetUrl( id: string, width: number, height: number, x: number, y: number, cropWidth: number, cropHeight: number ): Promise { const response = await handleFetch( stringifyQuery(`/assets/generate-url/${id}`, { width, height, x, y, cropWidth, cropHeight }) ); return response.json(); } public static async getPreviewUrlForAssetId(id: string, variantId: string, width = 200): Promise { const asset = await AssetApi.getAssetById(id); return await AssetApi.getPreviewUrlForAsset(asset, variantId, width); } public static async getPreviewUrlForAsset(asset: Asset | null, variantId: string | null = null, width = 200): Promise { if (!asset || !asset.contentType) { return null; } if (asset.contentType.indexOf('mp4') > -1) { return mp4Image; } if (asset.contentType.indexOf('pdf') > -1) { return pdfImage; } if (asset.contentType.indexOf('zip') > -1) { return zipImage; } if (asset.contentType.indexOf('webm') > -1) { return webmImage; } const foundVariant = asset.variants.find((variant: AssetVariant) => variant.id === variantId); if (!variantId || !foundVariant) { // Note: it was possible to upload a SVG image before, now there is no decoder for it anymore. return asset.contentType.startsWith('image/svg') ? asset.blobstoreUrl : asset.imageUrl.startsWith('/image/') // no resized version yet? ? asset.blobstoreUrl : asset.imageUrl; } const aspectRatio = asset.height / asset.width; const { crop } = foundVariant; return await AssetApi.createPublicAssetUrl(asset.id, width, aspectRatio * width, crop.x, crop.y, crop.width, crop.height); } } export type AssetSearchResponse = { result: SearchResponse; timestamp: number }; export type AssetSearchResult = SearchResponse;