Skip loading videos into memory for performance
This commit is contained in:
parent
c6904476f4
commit
5d0469adef
1 changed files with 38 additions and 5 deletions
|
@ -2,7 +2,9 @@
|
|||
* @prettier
|
||||
*/
|
||||
import is from '@sindresorhus/is';
|
||||
import { partition, sortBy } from 'lodash';
|
||||
|
||||
import * as MIME from '../../../../types/MIME';
|
||||
import { arrayBufferToObjectURL } from '../../../../util/arrayBufferToObjectURL';
|
||||
import { Attachment } from '../../../../types/Attachment';
|
||||
import { MapAsync } from '../../../../types/MapAsync';
|
||||
|
@ -16,24 +18,55 @@ export type Message = {
|
|||
const DEFAULT_CONTENT_TYPE: MIMEType = 'application/octet-stream' as MIMEType;
|
||||
|
||||
export const loadWithObjectURL = (loadMessage: MapAsync<Message>) => async (
|
||||
media: Array<Message>
|
||||
messages: Array<Message>
|
||||
): Promise<Array<Message>> => {
|
||||
if (!is.function_(loadMessage)) {
|
||||
throw new TypeError("'loadMessage' must be a function");
|
||||
}
|
||||
if (!is.array(media)) {
|
||||
throw new TypeError("'media' must be a function");
|
||||
if (!is.array(messages)) {
|
||||
throw new TypeError("'messages' must be an array");
|
||||
}
|
||||
|
||||
const mediaWithAttachmentData = await Promise.all(media.map(loadMessage));
|
||||
return mediaWithAttachmentData.map(withObjectURL);
|
||||
// Messages with video are too expensive to load into memory, so we don’t:
|
||||
const [messagesWithVideo, messagesWithoutVideo] = partition(
|
||||
messages,
|
||||
hasVideoAttachment
|
||||
);
|
||||
const loadedMessagesWithoutVideo = await Promise.all(
|
||||
messagesWithoutVideo.map(loadMessage)
|
||||
);
|
||||
const loadedMessages = sortBy(
|
||||
[...messagesWithVideo, ...loadedMessagesWithoutVideo],
|
||||
message => -message.received_at
|
||||
);
|
||||
|
||||
return loadedMessages.map(withObjectURL);
|
||||
};
|
||||
|
||||
const hasVideoAttachment = (message: Message): boolean =>
|
||||
message.attachments.some(
|
||||
attachment =>
|
||||
!is.undefined(attachment.contentType) &&
|
||||
MIME.isVideo(attachment.contentType)
|
||||
);
|
||||
|
||||
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') {
|
||||
throw new TypeError('`attachment.contentType` is required');
|
||||
}
|
||||
|
||||
if (MIME.isVideo(attachment.contentType)) {
|
||||
return {
|
||||
...message,
|
||||
objectURL: 'images/video.svg',
|
||||
};
|
||||
}
|
||||
|
||||
const objectURL = arrayBufferToObjectURL({
|
||||
data: attachment.data,
|
||||
type: attachment.contentType || DEFAULT_CONTENT_TYPE,
|
||||
|
|
Loading…
Add table
Reference in a new issue