Improve typing (#8674)
This commit is contained in:
parent
fe21ec8715
commit
9a1410e34c
1 changed files with 29 additions and 18 deletions
|
@ -23,7 +23,7 @@ import encrypt from "matrix-encrypt-attachment";
|
||||||
import extractPngChunks from "png-chunks-extract";
|
import extractPngChunks from "png-chunks-extract";
|
||||||
import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials";
|
import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { IEventRelation, ISendEventResponse, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
import { IEventRelation, ISendEventResponse, MatrixError, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||||
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
|
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
|
||||||
|
|
||||||
import { IEncryptedFile, IMediaEventInfo } from "./customisations/models/IMediaEventContent";
|
import { IEncryptedFile, IMediaEventInfo } from "./customisations/models/IMediaEventContent";
|
||||||
|
@ -64,10 +64,7 @@ interface IMediaConfig {
|
||||||
interface IContent {
|
interface IContent {
|
||||||
body: string;
|
body: string;
|
||||||
msgtype: string;
|
msgtype: string;
|
||||||
info: {
|
info: IMediaEventInfo;
|
||||||
size: number;
|
|
||||||
mimetype?: string;
|
|
||||||
};
|
|
||||||
file?: string;
|
file?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +126,9 @@ const IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT = 0.1; // 10%
|
||||||
// We don't apply these thresholds to video thumbnails as a poster image is always useful
|
// We don't apply these thresholds to video thumbnails as a poster image is always useful
|
||||||
// and videos tend to be much larger.
|
// and videos tend to be much larger.
|
||||||
|
|
||||||
|
// Image mime types for which to always include a thumbnail for even if it is larger than the input for wider support.
|
||||||
|
const ALWAYS_INCLUDE_THUMBNAIL = ["image/avif", "image/webp"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the metadata for an image file and create and upload a thumbnail of the image.
|
* Read the metadata for an image file and create and upload a thumbnail of the image.
|
||||||
*
|
*
|
||||||
|
@ -137,7 +137,11 @@ const IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT = 0.1; // 10%
|
||||||
* @param {File} imageFile The image to read and thumbnail.
|
* @param {File} imageFile The image to read and thumbnail.
|
||||||
* @return {Promise} A promise that resolves with the attachment info.
|
* @return {Promise} A promise that resolves with the attachment info.
|
||||||
*/
|
*/
|
||||||
async function infoForImageFile(matrixClient: MatrixClient, roomId: string, imageFile: File) {
|
async function infoForImageFile(
|
||||||
|
matrixClient: MatrixClient,
|
||||||
|
roomId: string,
|
||||||
|
imageFile: File,
|
||||||
|
): Promise<Partial<IMediaEventInfo>> {
|
||||||
let thumbnailType = "image/png";
|
let thumbnailType = "image/png";
|
||||||
if (imageFile.type === "image/jpeg") {
|
if (imageFile.type === "image/jpeg") {
|
||||||
thumbnailType = "image/jpeg";
|
thumbnailType = "image/jpeg";
|
||||||
|
@ -149,7 +153,7 @@ async function infoForImageFile(matrixClient: MatrixClient, roomId: string, imag
|
||||||
const imageInfo = result.info;
|
const imageInfo = result.info;
|
||||||
|
|
||||||
// For lesser supported image types, always include the thumbnail even if it is larger
|
// For lesser supported image types, always include the thumbnail even if it is larger
|
||||||
if (!["image/avif", "image/webp"].includes(imageFile.type)) {
|
if (!ALWAYS_INCLUDE_THUMBNAIL.includes(imageFile.type)) {
|
||||||
// we do all sizing checks here because we still rely on thumbnail generation for making a blurhash from.
|
// we do all sizing checks here because we still rely on thumbnail generation for making a blurhash from.
|
||||||
const sizeDifference = imageFile.size - imageInfo.thumbnail_info.size;
|
const sizeDifference = imageFile.size - imageInfo.thumbnail_info.size;
|
||||||
if (
|
if (
|
||||||
|
@ -178,7 +182,7 @@ async function infoForImageFile(matrixClient: MatrixClient, roomId: string, imag
|
||||||
* @param {File} videoFile The file to load in an video element.
|
* @param {File} videoFile The file to load in an video element.
|
||||||
* @return {Promise} A promise that resolves with the video image element.
|
* @return {Promise} A promise that resolves with the video image element.
|
||||||
*/
|
*/
|
||||||
function loadVideoElement(videoFile): Promise<HTMLVideoElement> {
|
function loadVideoElement(videoFile: File): Promise<HTMLVideoElement> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// Load the file into an html element
|
// Load the file into an html element
|
||||||
const video = document.createElement("video");
|
const video = document.createElement("video");
|
||||||
|
@ -224,7 +228,11 @@ function loadVideoElement(videoFile): Promise<HTMLVideoElement> {
|
||||||
* @param {File} videoFile The video to read and thumbnail.
|
* @param {File} videoFile The video to read and thumbnail.
|
||||||
* @return {Promise} A promise that resolves with the attachment info.
|
* @return {Promise} A promise that resolves with the attachment info.
|
||||||
*/
|
*/
|
||||||
function infoForVideoFile(matrixClient, roomId, videoFile) {
|
function infoForVideoFile(
|
||||||
|
matrixClient: MatrixClient,
|
||||||
|
roomId: string,
|
||||||
|
videoFile: File,
|
||||||
|
): Promise<Partial<IMediaEventInfo>> {
|
||||||
const thumbnailType = "image/jpeg";
|
const thumbnailType = "image/jpeg";
|
||||||
|
|
||||||
let videoInfo: Partial<IMediaEventInfo>;
|
let videoInfo: Partial<IMediaEventInfo>;
|
||||||
|
@ -449,7 +457,7 @@ export default class ContentMessages {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancelUpload(promise: Promise<any>, matrixClient: MatrixClient): void {
|
public cancelUpload(promise: IAbortablePromise<any>, matrixClient: MatrixClient): void {
|
||||||
const upload = this.inprogress.find(item => item.promise === promise);
|
const upload = this.inprogress.find(item => item.promise === promise);
|
||||||
if (upload) {
|
if (upload) {
|
||||||
upload.canceled = true;
|
upload.canceled = true;
|
||||||
|
@ -466,12 +474,12 @@ export default class ContentMessages {
|
||||||
replyToEvent: MatrixEvent | undefined,
|
replyToEvent: MatrixEvent | undefined,
|
||||||
promBefore: Promise<any>,
|
promBefore: Promise<any>,
|
||||||
) {
|
) {
|
||||||
const content: IContent = {
|
const content: Omit<IContent, "info"> & { info: Partial<IMediaEventInfo> } = {
|
||||||
body: file.name || 'Attachment',
|
body: file.name || 'Attachment',
|
||||||
info: {
|
info: {
|
||||||
size: file.size,
|
size: file.size,
|
||||||
},
|
},
|
||||||
msgtype: "", // set later
|
msgtype: MsgType.File, // set more specifically later
|
||||||
};
|
};
|
||||||
|
|
||||||
attachRelation(content, relation);
|
attachRelation(content, relation);
|
||||||
|
@ -497,6 +505,7 @@ export default class ContentMessages {
|
||||||
Object.assign(content.info, imageInfo);
|
Object.assign(content.info, imageInfo);
|
||||||
resolve();
|
resolve();
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
|
// Failed to thumbnail, fall back to uploading an m.file
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
content.msgtype = MsgType.File;
|
content.msgtype = MsgType.File;
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -510,6 +519,8 @@ export default class ContentMessages {
|
||||||
Object.assign(content.info, videoInfo);
|
Object.assign(content.info, videoInfo);
|
||||||
resolve();
|
resolve();
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
|
// Failed to thumbnail, fall back to uploading an m.file
|
||||||
|
logger.error(e);
|
||||||
content.msgtype = MsgType.File;
|
content.msgtype = MsgType.File;
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
@ -541,8 +552,8 @@ export default class ContentMessages {
|
||||||
dis.dispatch<UploadProgressPayload>({ action: Action.UploadProgress, upload });
|
dis.dispatch<UploadProgressPayload>({ action: Action.UploadProgress, upload });
|
||||||
}
|
}
|
||||||
|
|
||||||
let error;
|
let error: MatrixError;
|
||||||
return prom.then(function() {
|
return prom.then(() => {
|
||||||
if (upload.canceled) throw new UploadCanceledError();
|
if (upload.canceled) throw new UploadCanceledError();
|
||||||
// XXX: upload.promise must be the promise that
|
// XXX: upload.promise must be the promise that
|
||||||
// is returned by uploadFile as it has an abort()
|
// is returned by uploadFile as it has an abort()
|
||||||
|
@ -567,11 +578,11 @@ export default class ContentMessages {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return prom;
|
return prom;
|
||||||
}, function(err) {
|
}, function(err: MatrixError) {
|
||||||
error = err;
|
error = err;
|
||||||
if (!upload.canceled) {
|
if (!upload.canceled) {
|
||||||
let desc = _t("The file '%(fileName)s' failed to upload.", { fileName: upload.fileName });
|
let desc = _t("The file '%(fileName)s' failed to upload.", { fileName: upload.fileName });
|
||||||
if (err.http_status === 413) {
|
if (err.httpStatus === 413) {
|
||||||
desc = _t(
|
desc = _t(
|
||||||
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads",
|
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads",
|
||||||
{ fileName: upload.fileName },
|
{ fileName: upload.fileName },
|
||||||
|
@ -593,7 +604,7 @@ export default class ContentMessages {
|
||||||
// 413: File was too big or upset the server in some way:
|
// 413: File was too big or upset the server in some way:
|
||||||
// clear the media size limit so we fetch it again next time
|
// clear the media size limit so we fetch it again next time
|
||||||
// we try to upload
|
// we try to upload
|
||||||
if (error && error.http_status === 413) {
|
if (error?.httpStatus === 413) {
|
||||||
this.mediaConfig = null;
|
this.mediaConfig = null;
|
||||||
}
|
}
|
||||||
dis.dispatch<UploadErrorPayload>({ action: Action.UploadFailed, upload, error });
|
dis.dispatch<UploadErrorPayload>({ action: Action.UploadFailed, upload, error });
|
||||||
|
@ -613,7 +624,7 @@ export default class ContentMessages {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ensureMediaConfigFetched(matrixClient: MatrixClient) {
|
private ensureMediaConfigFetched(matrixClient: MatrixClient): Promise<void> {
|
||||||
if (this.mediaConfig !== null) return;
|
if (this.mediaConfig !== null) return;
|
||||||
|
|
||||||
logger.log("[Media Config] Fetching");
|
logger.log("[Media Config] Fetching");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue