Display icon for unsupported file formats
Still allows users to download media.
This commit is contained in:
parent
623bdd9284
commit
90329a2764
3 changed files with 101 additions and 7 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
## Image (supported format)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
|
@ -9,3 +11,51 @@ const noop = () => {};
|
||||||
/>
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Image (unsupported format)
|
||||||
|
|
||||||
|
```js
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
<div style={{ position: 'relative', width: '100%', height: 500 }}>
|
||||||
|
<Lightbox objectURL="foo.tif" contentType="image/tiff" onSave={noop} />
|
||||||
|
</div>;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Video (supported format)
|
||||||
|
|
||||||
|
```js
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
<div style={{ position: 'relative', width: '100%', height: 500 }}>
|
||||||
|
<Lightbox
|
||||||
|
objectURL="fixtures/pixabay-Soap-Bubble-7141.mp4"
|
||||||
|
contentType="video/mp4"
|
||||||
|
onSave={noop}
|
||||||
|
/>
|
||||||
|
</div>;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Video (unsupported format)
|
||||||
|
|
||||||
|
```js
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
<div style={{ position: 'relative', width: '100%', height: 500 }}>
|
||||||
|
<Lightbox objectURL="foo.mov" contentType="video/quicktime" onSave={noop} />
|
||||||
|
</div>;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Unsupported file format
|
||||||
|
|
||||||
|
```js
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
<div style={{ position: 'relative', width: '100%', height: 600 }}>
|
||||||
|
<Lightbox
|
||||||
|
objectURL="tsconfig.json"
|
||||||
|
contentType="application/json"
|
||||||
|
onSave={noop}
|
||||||
|
/>
|
||||||
|
</div>;
|
||||||
|
```
|
||||||
|
|
|
@ -3,8 +3,10 @@ import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
|
|
||||||
|
import * as Colors from './styles/Colors';
|
||||||
import * as GoogleChrome from '../util/GoogleChrome';
|
import * as GoogleChrome from '../util/GoogleChrome';
|
||||||
import * as MIME from '../types/MIME';
|
import * as MIME from '../types/MIME';
|
||||||
|
import { colorSVG } from '../styles/colorSVG';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
close: () => void;
|
close: () => void;
|
||||||
|
@ -50,6 +52,13 @@ const styles = {
|
||||||
maxHeight: '100%',
|
maxHeight: '100%',
|
||||||
objectFit: 'contain',
|
objectFit: 'contain',
|
||||||
} as React.CSSProperties,
|
} as React.CSSProperties,
|
||||||
|
video: {
|
||||||
|
flexGrow: 1,
|
||||||
|
flexShrink: 0,
|
||||||
|
maxWidth: '100%',
|
||||||
|
maxHeight: '100%',
|
||||||
|
objectFit: 'contain',
|
||||||
|
} as React.CSSProperties,
|
||||||
controlsOffsetPlaceholder: {
|
controlsOffsetPlaceholder: {
|
||||||
width: CONTROLS_WIDTH,
|
width: CONTROLS_WIDTH,
|
||||||
marginRight: CONTROLS_SPACING,
|
marginRight: CONTROLS_SPACING,
|
||||||
|
@ -110,6 +119,25 @@ const IconButtonPlaceholder = () => (
|
||||||
<div style={styles.iconButtonPlaceholder} />
|
<div style={styles.iconButtonPlaceholder} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const Icon = ({
|
||||||
|
onClick,
|
||||||
|
url,
|
||||||
|
}: {
|
||||||
|
onClick?: (
|
||||||
|
event: React.MouseEvent<HTMLImageElement | HTMLDivElement>
|
||||||
|
) => void;
|
||||||
|
url: string;
|
||||||
|
}) => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.image,
|
||||||
|
...colorSVG(url, Colors.ICON_SECONDARY),
|
||||||
|
maxWidth: 200,
|
||||||
|
}}
|
||||||
|
onClick={onClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
export class Lightbox extends React.Component<Props, {}> {
|
export class Lightbox extends React.Component<Props, {}> {
|
||||||
private containerRef: HTMLDivElement | null = null;
|
private containerRef: HTMLDivElement | null = null;
|
||||||
|
|
||||||
|
@ -172,8 +200,8 @@ export class Lightbox extends React.Component<Props, {}> {
|
||||||
objectURL: string;
|
objectURL: string;
|
||||||
contentType: MIME.MIMEType;
|
contentType: MIME.MIMEType;
|
||||||
}) => {
|
}) => {
|
||||||
const isImage = GoogleChrome.isImageTypeSupported(contentType);
|
const isImageTypeSupported = GoogleChrome.isImageTypeSupported(contentType);
|
||||||
if (isImage) {
|
if (isImageTypeSupported) {
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
style={styles.image}
|
style={styles.image}
|
||||||
|
@ -183,18 +211,31 @@ export class Lightbox extends React.Component<Props, {}> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isVideo = GoogleChrome.isVideoTypeSupported(contentType);
|
const isVideoTypeSupported = GoogleChrome.isVideoTypeSupported(contentType);
|
||||||
if (isVideo) {
|
if (isVideoTypeSupported) {
|
||||||
return (
|
return (
|
||||||
<video controls={true}>
|
<video controls={true} style={styles.video}>
|
||||||
<source src={objectURL} />
|
<source src={objectURL} />
|
||||||
</video>
|
</video>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isUnsupportedImageType =
|
||||||
|
!isImageTypeSupported && MIME.isImage(contentType);
|
||||||
|
const isUnsupportedVideoType =
|
||||||
|
!isVideoTypeSupported && MIME.isVideo(contentType);
|
||||||
|
if (isUnsupportedImageType || isUnsupportedVideoType) {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
url={isUnsupportedVideoType ? 'images/video.svg' : 'images/image.svg'}
|
||||||
|
onClick={this.onObjectClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line no-console
|
// tslint:disable-next-line no-console
|
||||||
console.log('Lightbox: Unexpected content type', { contentType });
|
console.log('Lightbox: Unexpected content type', { contentType });
|
||||||
return null;
|
return <Icon onClick={this.onObjectClick} url="images/file.svg" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
private setContainerRef = (value: HTMLDivElement) => {
|
private setContainerRef = (value: HTMLDivElement) => {
|
||||||
|
@ -242,7 +283,9 @@ export class Lightbox extends React.Component<Props, {}> {
|
||||||
this.onClose();
|
this.onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onObjectClick = (event: React.MouseEvent<HTMLImageElement>) => {
|
private onObjectClick = (
|
||||||
|
event: React.MouseEvent<HTMLImageElement | HTMLDivElement>
|
||||||
|
) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.onClose();
|
this.onClose();
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
* @prettier
|
* @prettier
|
||||||
*/
|
*/
|
||||||
export const TEXT_SECONDARY = '#bbb';
|
export const TEXT_SECONDARY = '#bbb';
|
||||||
|
export const ICON_SECONDARY = '#ccc';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue