Merge pull request #5624 from strapi/ml/fix-img-cache

ML/fix img cache
This commit is contained in:
cyril lopez 2020-03-30 09:54:57 +02:00 committed by GitHub
commit c18f33ee02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 71 additions and 40 deletions

View File

@ -110,6 +110,7 @@ export { default as getYupInnerErrors } from './utils/getYupInnerErrors';
export { default as generateFiltersFromSearch } from './utils/generateFiltersFromSearch'; export { default as generateFiltersFromSearch } from './utils/generateFiltersFromSearch';
export { default as generateSearchFromFilters } from './utils/generateSearchFromFilters'; export { default as generateSearchFromFilters } from './utils/generateSearchFromFilters';
export { default as generateSearchFromObject } from './utils/generateSearchFromObject'; export { default as generateSearchFromObject } from './utils/generateSearchFromObject';
export { default as prefixFileUrlWithBackendUrl } from './utils/prefixFileUrlWithBackendUrl';
// SVGS // SVGS
export { default as LayoutIcon } from './svgs/Layout'; export { default as LayoutIcon } from './svgs/Layout';

View File

@ -1,5 +1,5 @@
const prefixFileUrlWithBackendUrl = fileURL => { const prefixFileUrlWithBackendUrl = fileURL => {
return fileURL.startsWith('/') ? `${strapi.backendURL}${fileURL}` : fileURL; return !!fileURL && fileURL.startsWith('/') ? `${strapi.backendURL}${fileURL}` : fileURL;
}; };
export default prefixFileUrlWithBackendUrl; export default prefixFileUrlWithBackendUrl;

View File

@ -1,6 +1,6 @@
import prefixFileUrlWithBackendUrl from '../prefixFileUrlWithBackendUrl'; import prefixFileUrlWithBackendUrl from '../prefixFileUrlWithBackendUrl';
describe('UPLOAD | utils | prefixFileUrlWithBackendUrl', () => { describe('HELPER_PLUGIN | utils | prefixFileUrlWithBackendUrl', () => {
it("should add the strapi back-end url if the file's url startsWith '/'", () => { it("should add the strapi back-end url if the file's url startsWith '/'", () => {
const data = '/upload/test'; const data = '/upload/test';
const expected = 'http://localhost:1337/upload/test'; const expected = 'http://localhost:1337/upload/test';
@ -14,4 +14,11 @@ describe('UPLOAD | utils | prefixFileUrlWithBackendUrl', () => {
expect(prefixFileUrlWithBackendUrl(data)).toEqual(expected); expect(prefixFileUrlWithBackendUrl(data)).toEqual(expected);
}); });
it('should return the data if the url is not a string', () => {
const data = null;
const expected = null;
expect(prefixFileUrlWithBackendUrl(data)).toEqual(expected);
});
}); });

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { isArray, includes, isEmpty } from 'lodash'; import { get, isArray, includes, isEmpty } from 'lodash';
import { prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
import DefaultIcon from '../../icons/Na'; import DefaultIcon from '../../icons/Na';
import { import {
StyledMediaPreviewList, StyledMediaPreviewList,
@ -13,12 +14,11 @@ import {
const IMAGE_PREVIEW_COUNT = 3; const IMAGE_PREVIEW_COUNT = 3;
function MediaPreviewList({ hoverable, files }) { function MediaPreviewList({ hoverable, files }) {
const getFileType = fileName => fileName.split('.').slice(-1)[0]; const getFileType = fileName => (fileName ? fileName.split('.').slice(-1)[0] : null);
const getSrc = fileURL =>
fileURL.startsWith('/') ? `${strapi.backendURL}${fileURL}` : fileURL;
const renderImage = image => { const renderImage = image => {
const { name, size, url } = image; const { name, size, url } = image;
const fileUrl = get(image, ['formats', 'thumbnail', 'url'], url);
if (size > 2000) { if (size > 2000) {
return renderFile(image); return renderFile(image);
@ -27,9 +27,9 @@ function MediaPreviewList({ hoverable, files }) {
return ( return (
<MediaPreviewImage className={hoverable ? 'hoverable' : ''}> <MediaPreviewImage className={hoverable ? 'hoverable' : ''}>
<div> <div>
<img src={getSrc(url)} alt={`${name}`} /> <img src={prefixFileUrlWithBackendUrl(fileUrl)} alt={`${name}`} />
</div> </div>
<img src={getSrc(url)} alt={`${name}`} /> <img src={prefixFileUrlWithBackendUrl(fileUrl)} alt={`${name}`} />
</MediaPreviewImage> </MediaPreviewImage>
); );
}; };
@ -40,10 +40,16 @@ function MediaPreviewList({ hoverable, files }) {
return ( return (
<MediaPreviewFile className={hoverable ? 'hoverable' : ''}> <MediaPreviewFile className={hoverable ? 'hoverable' : ''}>
<div> {fileType ? (
<span>{fileType}</span> <div>
<i className={`far fa-file-${fileType}`} /> <span>{fileType}</span>
</div> </div>
) : (
<MediaPreviewItem>
<DefaultIcon />
</MediaPreviewItem>
)}
<span>{name}</span> <span>{name}</span>
</MediaPreviewFile> </MediaPreviewFile>
); );
@ -73,8 +79,7 @@ function MediaPreviewList({ hoverable, files }) {
return files.map((file, index) => { return files.map((file, index) => {
return ( return (
<React.Fragment key={JSON.stringify(file)}> <React.Fragment key={JSON.stringify(file)}>
{index === IMAGE_PREVIEW_COUNT && {index === IMAGE_PREVIEW_COUNT && files.length > IMAGE_PREVIEW_COUNT + 1
files.length > IMAGE_PREVIEW_COUNT + 1
? renderText(files.length - IMAGE_PREVIEW_COUNT) ? renderText(files.length - IMAGE_PREVIEW_COUNT)
: renderItem(file)} : renderItem(file)}
</React.Fragment> </React.Fragment>

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { memo } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { formatBytes, getExtension, getType } from '../../utils'; import { formatBytes, getExtension, getType } from '../../utils';
@ -98,4 +98,4 @@ Card.propTypes = {
withFileCaching: PropTypes.bool, withFileCaching: PropTypes.bool,
}; };
export default Card; export default memo(Card);

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { memo, useRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { getExtension, getType } from '../../utils'; import { getExtension, getType } from '../../utils';
@ -12,6 +12,7 @@ import Image from './Image';
const CardPreview = ({ hasError, hasIcon, url, previewUrl, type, withFileCaching }) => { const CardPreview = ({ hasError, hasIcon, url, previewUrl, type, withFileCaching }) => {
const isFile = getType(type) === 'file'; const isFile = getType(type) === 'file';
const isVideo = getType(type) === 'video'; const isVideo = getType(type) === 'video';
const cacheRef = useRef(performance.now());
if (hasError) { if (hasError) {
return ( return (
@ -36,7 +37,7 @@ const CardPreview = ({ hasError, hasIcon, url, previewUrl, type, withFileCaching
) : ( ) : (
// Adding performance.now forces the browser no to cache the img // Adding performance.now forces the browser no to cache the img
// https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images // https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
<Image src={`${url}${withFileCaching ? `?${performance.now()}` : ''}`} /> <Image src={`${url}${withFileCaching ? `?${cacheRef.current}` : ''}`} />
)} )}
</Wrapper> </Wrapper>
); );
@ -60,4 +61,4 @@ CardPreview.propTypes = {
withFileCaching: PropTypes.bool, withFileCaching: PropTypes.bool,
}; };
export default CardPreview; export default memo(CardPreview);

View File

@ -13,10 +13,10 @@ import axios from 'axios';
import { get } from 'lodash'; import { get } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Inputs } from '@buffetjs/custom'; import { Inputs } from '@buffetjs/custom';
import { useGlobalContext } from 'strapi-helper-plugin'; import { useGlobalContext, prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
import Cropper from 'cropperjs'; import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css'; import 'cropperjs/dist/cropper.css';
import { createFileToDownloadName, getTrad, prefixFileUrlWithBackendUrl } from '../../utils'; import { createFileToDownloadName, getTrad } from '../../utils';
import CardControl from '../CardControl'; import CardControl from '../CardControl';
import CardControlsWrapper from '../CardControlsWrapper'; import CardControlsWrapper from '../CardControlsWrapper';
import CardPreview from '../CardPreview'; import CardPreview from '../CardPreview';

View File

@ -1,12 +1,13 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
import CardPreview from '../CardPreview'; import CardPreview from '../CardPreview';
import Flex from '../Flex'; import Flex from '../Flex';
import Chevron from './Chevron'; import Chevron from './Chevron';
const InputFilePreview = ({ file, onClick, isSlider }) => { const InputFilePreview = ({ file, onClick, isSlider }) => {
const fileUrl = file.url.startsWith('/') ? `${strapi.backendURL}${file.url}` : file.url; const fileUrl = prefixFileUrlWithBackendUrl(file.url);
return ( return (
<Flex <Flex

View File

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Checkbox } from '@buffetjs/core'; import { Checkbox } from '@buffetjs/core';
import { get } from 'lodash'; import { get } from 'lodash';
import { prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
import DraggableCard from './DraggableCard'; import DraggableCard from './DraggableCard';
import CardControlsWrapper from '../CardControlsWrapper'; import CardControlsWrapper from '../CardControlsWrapper';
import ListWrapper from '../ListWrapper'; import ListWrapper from '../ListWrapper';
@ -18,10 +19,10 @@ const SortableList = ({ data, moveAsset, onChange, onClickEditFile, selectedItem
const { id } = item; const { id } = item;
const url = get(item, ['formats', 'thumbnail', 'url'], ''); const url = get(item, ['formats', 'thumbnail', 'url'], '');
const checked = selectedItems.findIndex(file => file.id === id) !== -1; const checked = selectedItems.findIndex(file => file.id === id) !== -1;
const fileUrl = url.startsWith('/') ? `${strapi.backendURL}${url}` : url; const fileUrl = prefixFileUrlWithBackendUrl(url);
return ( return (
<div className="col-xs-12 col-md-6 col-xl-3" key={id}> <div className="col-xs-12 col-md-6 col-xl-3" key={id || index}>
<DraggableCard <DraggableCard
checked={checked} checked={checked}
{...item} {...item}

View File

@ -1,5 +1,7 @@
// Source: https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript // Source: https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
function formatBytes(bytes, decimals) { function formatBytes(receivedBytes, decimals) {
const bytes = receivedBytes * 1000;
if (bytes < 1) { if (bytes < 1) {
return '0B'; return '0B';
} }

View File

@ -1,3 +1,3 @@
const getExtension = mime => mime.split(/[\s/]+/)[1]; const getExtension = mime => (mime ? mime.split(/[\s/]+/)[1] : 'undefined');
export default getExtension; export default getExtension;

View File

@ -1,4 +1,8 @@
const getType = mime => { const getType = mime => {
if (!mime) {
return 'file';
}
const type = mime.split(/[\s/]+/)[0]; const type = mime.split(/[\s/]+/)[0];
if (type === 'image' || type === 'video') { if (type === 'image' || type === 'video') {

View File

@ -11,4 +11,3 @@ export { default as getRequestUrl } from './getRequestUrl';
export { default as getTrad } from './getTrad'; export { default as getTrad } from './getTrad';
export { default as getType } from './getType'; export { default as getType } from './getType';
export { default as ItemTypes } from './ItemTypes'; export { default as ItemTypes } from './ItemTypes';
export { default as prefixFileUrlWithBackendUrl } from './prefixFileUrlWithBackendUrl';

View File

@ -6,28 +6,24 @@ describe('UPLOAD | components | EditForm | utils', () => {
expect(formatBytes(0)).toEqual('0B'); expect(formatBytes(0)).toEqual('0B');
}); });
it('should return 0B if less than 1 bytes is passed', () => { it('should return 900B if 0.9 bytes is passed', () => {
expect(formatBytes(0.9)).toEqual('0B'); expect(formatBytes(0.9)).toEqual('900B');
});
it('should return 1KB if 1024 Bytes is passed', () => {
expect(formatBytes(1024)).toEqual('1KB');
}); });
it("should return 1KB if '1024' Bytes is passed", () => { it("should return 1KB if '1024' Bytes is passed", () => {
expect(formatBytes('1024')).toEqual('1KB'); expect(formatBytes('1024')).toEqual('1000KB');
}); });
it('should return 1.21KB if 1034 Bytes is passed', () => { it('should return 1.18MB if 1034 Bytes is passed', () => {
expect(formatBytes(1234)).toEqual('1.21KB'); expect(formatBytes(1234)).toEqual('1.18MB');
}); });
it('should return 1.21KB if 1034 Bytes is passed with 3 decimals', () => { it('should return 1.177MB if 1234 Bytes is passed with 3 decimals', () => {
expect(formatBytes(1234, 3)).toEqual('1.205KB'); expect(formatBytes(1234, 3)).toEqual('1.177MB');
}); });
it('should return 1 MB if 1.1e+6 Bytes is passed', () => { it('should return 1 GB if 1.1e+6 Bytes is passed', () => {
expect(formatBytes(1100000, 0)).toEqual('1MB'); expect(formatBytes(1100000, 0)).toEqual('1GB');
}); });
}); });
}); });

View File

@ -1,6 +1,13 @@
import getExtension from '../getExtension'; import getExtension from '../getExtension';
describe('UPLOAD | utils | getExtension', () => { describe('UPLOAD | utils | getExtension', () => {
it('should return undefined if mime does not exits', () => {
const mime = null;
const expected = 'undefined';
expect(getExtension(mime)).toEqual(expected);
});
it('should return png if mime string is image/png', () => { it('should return png if mime string is image/png', () => {
const mime = 'image/png'; const mime = 'image/png';
const expected = 'png'; const expected = 'png';

View File

@ -1,6 +1,13 @@
import getType from '../getType'; import getType from '../getType';
describe('UPLOAD | utils | getType', () => { describe('UPLOAD | utils | getType', () => {
it('should return file if mime does not exits', () => {
const mime = undefined;
const expected = 'file';
expect(getType(mime)).toEqual(expected);
});
it('should return image if mime string contains image', () => { it('should return image if mime string contains image', () => {
const mime = 'image/png'; const mime = 'image/png';
const expected = 'image'; const expected = 'image';