Implement video support in lightbox

pull/1/head
Daniel Gasienica 7 years ago
parent ac04f0648a
commit 45d6c7a5a8

@ -109,7 +109,8 @@
}
const props = {
imageURL: this.objectUrl,
objectURL: this.objectUrl,
contentType: this.model.contentType,
onSave: () => this.saveFile(),
// implicit: `close`
};

@ -600,25 +600,28 @@
const media = await loadMessages(rawMedia);
const saveAttachment = async ({ message } = {}) => {
const loadedMessage = await Signal.Migrations.loadMessage(message);
const attachment = loadedMessage.attachments[0];
const timestamp = loadedMessage.received_at;
const attachment = message.attachments[0];
const timestamp = message.received_at;
Signal.Types.AttachmentTS.save({ attachment, timestamp });
};
const onItemClick = async ({ message, type }) => {
const loadedMessage = Signal.Components.Types.Message
.withObjectURL(await Signal.Migrations.loadMessage(message));
switch (type) {
case 'documents': {
saveAttachment({ message });
saveAttachment({ message: loadedMessage });
break;
}
case 'media': {
const attachment = loadedMessage.attachments[0];
this.lightboxView = new Whisper.ReactWrapperView({
Component: Signal.Components.Lightbox,
props: {
imageURL: message.objectURL,
onSave: () => saveAttachment({ message }),
objectURL: loadedMessage.objectURL,
contentType: attachment.contentType,
onSave: () => saveAttachment({ message: loadedMessage }),
},
onClose: () => Signal.Backbone.Views.Lightbox.hide(),
});

@ -3,7 +3,8 @@ const noop = () => {};
<div style={{position: 'relative', width: '100%', height: 500}}>
<Lightbox
imageURL="https://placekitten.com/800/600"
objectURL="https://placekitten.com/800/600"
contentType="image/jpeg"
onNext={noop}
onPrevious={noop}
onSave={noop}

@ -4,13 +4,18 @@
import React from 'react';
import classNames from 'classnames';
import is from '@sindresorhus/is';
import * as GoogleChrome from '../util/GoogleChrome';
import * as MIME from '../types/MIME';
interface Props {
close: () => void;
imageURL?: string;
objectURL: string;
contentType: MIME.MIMEType | undefined;
onNext?: () => void;
onPrevious?: () => void;
onSave: () => void;
onSave?: () => void;
}
const styles = {
@ -67,7 +72,7 @@ export class Lightbox extends React.Component<Props, {}> {
}
public render() {
const { imageURL } = this.props;
const { contentType, objectURL } = this.props;
return (
<div
style={styles.container}
@ -75,11 +80,9 @@ export class Lightbox extends React.Component<Props, {}> {
ref={this.setContainerRef}
>
<div style={styles.objectContainer}>
<img
style={styles.image}
src={imageURL}
onClick={this.onImageClick}
/>
{!is.undefined(contentType)
? this.renderObject({ objectURL, contentType })
: null}
</div>
<div style={styles.controls}>
<IconButton type="close" onClick={this.onClose} />
@ -97,6 +100,38 @@ export class Lightbox extends React.Component<Props, {}> {
);
}
private renderObject = ({
objectURL,
contentType,
}: {
objectURL: string;
contentType: MIME.MIMEType;
}) => {
const isImage = GoogleChrome.isImageTypeSupported(contentType);
if (isImage) {
return (
<img
style={styles.image}
src={objectURL}
onClick={this.onObjectClick}
/>
);
}
const isVideo = GoogleChrome.isVideoTypeSupported(contentType);
if (isVideo) {
return (
<video controls>
<source src={objectURL} />
</video>
);
}
// tslint:disable-next-line no-console
console.log('Lightbox: Unexpected content type', { contentType });
return null;
};
private setContainerRef = (value: HTMLDivElement) => {
this.containerRef = value;
};
@ -125,7 +160,7 @@ export class Lightbox extends React.Component<Props, {}> {
this.onClose();
};
private onImageClick = (event: React.MouseEvent<HTMLImageElement>) => {
private onObjectClick = (event: React.MouseEvent<HTMLImageElement>) => {
event.stopPropagation();
this.onClose();
};

@ -8,7 +8,6 @@ import * as MIME from '../../../../types/MIME';
import { arrayBufferToObjectURL } from '../../../../util/arrayBufferToObjectURL';
import { Attachment } from '../../../../types/Attachment';
import { MapAsync } from '../../../../types/MapAsync';
import { MIMEType } from '../../../../types/MIME';
export type Message = {
id: string;
@ -16,8 +15,6 @@ export type Message = {
received_at: number;
} & { objectURL?: string };
const DEFAULT_CONTENT_TYPE: MIMEType = 'application/octet-stream' as MIMEType;
export const loadWithObjectURL = (loadMessage: MapAsync<Message>) => async (
messages: Array<Message>
): Promise<Array<Message>> => {
@ -51,17 +48,17 @@ const hasVideoAttachment = (message: Message): boolean =>
MIME.isVideo(attachment.contentType)
);
const withObjectURL = (message: Message): Message => {
export const withObjectURL = (message: Message): Message => {
if (message.attachments.length === 0) {
throw new TypeError('`message.attachments` cannot be empty');
}
const attachment = message.attachments[0];
if (typeof attachment.contentType === 'undefined') {
if (is.undefined(attachment.contentType)) {
throw new TypeError('`attachment.contentType` is required');
}
if (MIME.isVideo(attachment.contentType)) {
if (is.undefined(attachment.data) && MIME.isVideo(attachment.contentType)) {
return {
...message,
objectURL: 'images/video.svg',
@ -70,7 +67,7 @@ const withObjectURL = (message: Message): Message => {
const objectURL = arrayBufferToObjectURL({
data: attachment.data,
type: attachment.contentType || DEFAULT_CONTENT_TYPE,
type: attachment.contentType,
});
return {
...message,

Loading…
Cancel
Save