You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.2 KiB
JavaScript
106 lines
3.2 KiB
JavaScript
"use strict";
|
|
|
|
const Promise = require("bluebird");
|
|
const path = require("path");
|
|
const matchValue = require("match-value");
|
|
const defaultValue = require("default-value");
|
|
const thumbnailImage = require("../thumbnail-image");
|
|
const uploadFile = require("../upload-file");
|
|
const sendImageEvent = require("../send-image-event");
|
|
const universalImageMetadata = require("../universal-image-metadata");
|
|
|
|
const { validateArguments } = require("@validatem/core");
|
|
const required = require("@validatem/required");
|
|
const isInteger = require("@validatem/is-integer");
|
|
const isNonEmptyString = require("@validatem/is-non-empty-string");
|
|
const defaultTo = require("@validatem/default-to");
|
|
const isSession = require("@modular-matrix/is-session");
|
|
const isRoomID = require("../is-room-id");
|
|
const isPositive = require("../is-positive");
|
|
|
|
function thumbnailFilename(filename, mimetype) {
|
|
let extension = matchValue(mimetype, {
|
|
"image/png": "png",
|
|
"image/jpeg": "jpeg"
|
|
});
|
|
|
|
if (filename != null) {
|
|
let baseName = path.basename(filename, path.extname(filename));
|
|
return `thumbnail-${baseName}.${extension}`;
|
|
} else {
|
|
return `thumbnail.${extension}`;
|
|
}
|
|
}
|
|
|
|
module.exports = function sendImage(_session, _options) {
|
|
let [ session, options ] = validateArguments(arguments, {
|
|
session: [ required, isSession ],
|
|
options: [ required, {
|
|
roomID: [ required, isRoomID ],
|
|
description: [ required, isNonEmptyString ],
|
|
file: [ required ], // FIXME: Validate more strictly, something like isUploadable
|
|
filename: [ isNonEmptyString ],
|
|
thumbnail: [{
|
|
maximumWidth: [ required, isInteger, isPositive ],
|
|
maximumHeight: [ required, isInteger, isPositive ],
|
|
}, defaultTo({ maximumWidth: 800, maximumHeight: 600 }) ]
|
|
}]
|
|
});
|
|
|
|
return Promise.all([
|
|
universalImageMetadata(options.file),
|
|
uploadFile(session, {
|
|
file: options.file,
|
|
filename: options.filename
|
|
})
|
|
]).then(([ metadata, uploadResult ]) => {
|
|
let fullSizeMXC = uploadResult.url;
|
|
|
|
let desiredThumbnailMimetype = (metadata.mimetype === "image/jpeg")
|
|
? "image/jpeg"
|
|
: "image/png";
|
|
|
|
return Promise.try(() => {
|
|
return thumbnailImage({
|
|
session: session,
|
|
mxc: fullSizeMXC,
|
|
maximumWidth: options.thumbnail.maximumWidth,
|
|
maximumHeight: options.thumbnail.maximumHeight,
|
|
file: options.file,
|
|
mimetype: desiredThumbnailMimetype
|
|
});
|
|
}).then((thumbnail) => {
|
|
let thumbnailFile = defaultValue(thumbnail.blob, thumbnail.buffer);
|
|
let thumbnailFilesize = (thumbnail.buffer != null) ? thumbnail.buffer.length : thumbnail.blob.size;
|
|
|
|
return Promise.try(() => {
|
|
return uploadFile(session, {
|
|
file: thumbnailFile,
|
|
filename: thumbnailFilename(options.filename)
|
|
});
|
|
}).then((result) => {
|
|
let thumbnailMXC = result.url;
|
|
|
|
return sendImageEvent(session, {
|
|
roomID: options.roomID,
|
|
description: options.description,
|
|
image: {
|
|
url: fullSizeMXC,
|
|
displayWidth: metadata.width,
|
|
displayHeight: metadata.height,
|
|
mimetype: metadata.mimetype,
|
|
filesize: metadata.filesize
|
|
},
|
|
thumbnail: {
|
|
url: thumbnailMXC,
|
|
displayWidth: thumbnail.width,
|
|
displayHeight: thumbnail.height,
|
|
mimetype: defaultValue(thumbnail.mimetype, desiredThumbnailMimetype),
|
|
filesize: thumbnailFilesize
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
};
|