Reuse media content/info types from the js-sdk (#12308)
This commit is contained in:
parent
89eb884821
commit
431ae32304
19 changed files with 74 additions and 258 deletions
|
@ -76,6 +76,7 @@ module.exports = {
|
|||
group: [
|
||||
"matrix-js-sdk/src/**",
|
||||
"!matrix-js-sdk/src/matrix",
|
||||
"!matrix-js-sdk/src/types",
|
||||
"matrix-js-sdk/lib",
|
||||
"matrix-js-sdk/lib/",
|
||||
"matrix-js-sdk/lib/**",
|
||||
|
|
27
src/@types/matrix-js-sdk.d.ts
vendored
Normal file
27
src/@types/matrix-js-sdk.d.ts
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { BLURHASH_FIELD } from "../utils/image-media";
|
||||
|
||||
// Matrix JS SDK extensions
|
||||
declare module "matrix-js-sdk" {
|
||||
export interface FileInfo {
|
||||
/**
|
||||
* @see https://github.com/matrix-org/matrix-spec-proposals/pull/2448
|
||||
*/
|
||||
[BLURHASH_FIELD]?: string;
|
||||
}
|
||||
}
|
|
@ -28,19 +28,19 @@ import {
|
|||
UploadProgress,
|
||||
THREAD_RELATION_TYPE,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
ImageInfo,
|
||||
AudioInfo,
|
||||
VideoInfo,
|
||||
EncryptedFile,
|
||||
MediaEventContent,
|
||||
MediaEventInfo,
|
||||
} from "matrix-js-sdk/src/types";
|
||||
import encrypt from "matrix-encrypt-attachment";
|
||||
import extractPngChunks from "png-chunks-extract";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { removeElement } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import {
|
||||
AudioInfo,
|
||||
EncryptedFile,
|
||||
ImageInfo,
|
||||
IMediaEventContent,
|
||||
IMediaEventInfo,
|
||||
VideoInfo,
|
||||
} from "./customisations/models/IMediaEventContent";
|
||||
import dis from "./dispatcher/dispatcher";
|
||||
import { _t } from "./languageHandler";
|
||||
import Modal from "./Modal";
|
||||
|
@ -537,7 +537,7 @@ export default class ContentMessages {
|
|||
promBefore?: Promise<any>,
|
||||
): Promise<void> {
|
||||
const fileName = file.name || _t("common|attachment");
|
||||
const content: Omit<IMediaEventContent, "info"> & { info: Partial<IMediaEventInfo> } = {
|
||||
const content: Omit<MediaEventContent, "info"> & { info: Partial<MediaEventInfo> } = {
|
||||
body: fileName,
|
||||
info: {
|
||||
size: file.size,
|
||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
import React from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { IContent } from "matrix-js-sdk/src/matrix";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { Playback } from "../../../audio/Playback";
|
||||
import InlineSpinner from "../elements/InlineSpinner";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AudioPlayer from "../audio_messages/AudioPlayer";
|
||||
import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent";
|
||||
import MFileBody from "./MFileBody";
|
||||
import { IBodyProps } from "./IBodyProps";
|
||||
import { PlaybackManager } from "../../../audio/PlaybackManager";
|
||||
|
@ -67,7 +67,7 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
|
|||
// We should have a buffer to work with now: let's set it up
|
||||
|
||||
// Note: we don't actually need a waveform to render an audio event, but voice messages do.
|
||||
const content = this.props.mxEvent.getContent<IMediaEventContent & IContent>();
|
||||
const content = this.props.mxEvent.getContent<MediaEventContent & IContent>();
|
||||
const waveform = content?.["org.matrix.msc1767.audio"]?.waveform?.map((p: number) => p / 1024);
|
||||
|
||||
// We should have a buffer to work with now: let's set it up
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
import React, { AllHTMLAttributes, createRef } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import Modal from "../../../Modal";
|
||||
|
@ -23,7 +24,6 @@ import AccessibleButton from "../elements/AccessibleButton";
|
|||
import { mediaFromContent } from "../../../customisations/Media";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import { fileSize, presentableTextForFile } from "../../../utils/FileUtils";
|
||||
import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent";
|
||||
import { IBodyProps } from "./IBodyProps";
|
||||
import { FileDownloader } from "../../../utils/FileDownloader";
|
||||
import TextWithTooltip from "../elements/TextWithTooltip";
|
||||
|
@ -128,8 +128,8 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||
const media = mediaFromContent(this.props.mxEvent.getContent());
|
||||
return media.srcHttp;
|
||||
}
|
||||
private get content(): IMediaEventContent {
|
||||
return this.props.mxEvent.getContent<IMediaEventContent>();
|
||||
private get content(): MediaEventContent {
|
||||
return this.props.mxEvent.getContent<MediaEventContent>();
|
||||
}
|
||||
|
||||
private get fileName(): string {
|
||||
|
|
|
@ -21,6 +21,7 @@ import classNames from "classnames";
|
|||
import { CSSTransition, SwitchTransition } from "react-transition-group";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { ClientEvent, ClientEventHandlerMap } from "matrix-js-sdk/src/matrix";
|
||||
import { ImageContent } from "matrix-js-sdk/src/types";
|
||||
import { Tooltip } from "@vector-im/compound-web";
|
||||
|
||||
import MFileBody from "./MFileBody";
|
||||
|
@ -30,7 +31,6 @@ import SettingsStore from "../../../settings/SettingsStore";
|
|||
import Spinner from "../elements/Spinner";
|
||||
import { Media, mediaFromContent } from "../../../customisations/Media";
|
||||
import { BLURHASH_FIELD, createThumbnail } from "../../../utils/image-media";
|
||||
import { ImageContent } from "../../../customisations/models/IMediaEventContent";
|
||||
import ImageView from "../elements/ImageView";
|
||||
import { IBodyProps } from "./IBodyProps";
|
||||
import { ImageSize, suggestedSize as suggestedImageSize } from "../../../settings/enums/ImageSize";
|
||||
|
|
|
@ -15,9 +15,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { ImageContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import MImageBody from "./MImageBody";
|
||||
import { ImageContent } from "../../../customisations/models/IMediaEventContent";
|
||||
|
||||
const FORCED_IMAGE_HEIGHT = 44;
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ limitations under the License.
|
|||
|
||||
import React, { ComponentProps, ReactNode } from "react";
|
||||
import { Tooltip } from "@vector-im/compound-web";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import MImageBody from "./MImageBody";
|
||||
import { BLURHASH_FIELD } from "../../../utils/image-media";
|
||||
import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent";
|
||||
|
||||
export default class MStickerBody extends MImageBody {
|
||||
// Mostly empty to prevent default behaviour of MImageBody
|
||||
|
@ -80,7 +80,7 @@ export default class MStickerBody extends MImageBody {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected getBanner(content: IMediaEventContent): ReactNode {
|
||||
protected getBanner(content: MediaEventContent): ReactNode {
|
||||
return null; // we don't need a banner, we have a tooltip
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
import React, { ReactNode } from "react";
|
||||
import { decode } from "blurhash";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
@ -23,7 +24,6 @@ import SettingsStore from "../../../settings/SettingsStore";
|
|||
import InlineSpinner from "../elements/InlineSpinner";
|
||||
import { mediaFromContent } from "../../../customisations/Media";
|
||||
import { BLURHASH_FIELD } from "../../../utils/image-media";
|
||||
import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent";
|
||||
import { IBodyProps } from "./IBodyProps";
|
||||
import MFileBody from "./MFileBody";
|
||||
import { ImageSize, suggestedSize as suggestedVideoSize } from "../../../settings/enums/ImageSize";
|
||||
|
@ -62,7 +62,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
}
|
||||
|
||||
private getContentUrl(): string | undefined {
|
||||
const content = this.props.mxEvent.getContent<IMediaEventContent>();
|
||||
const content = this.props.mxEvent.getContent<MediaEventContent>();
|
||||
// During export, the content url will point to the MSC, which will later point to a local url
|
||||
if (this.props.forExport) return content.file?.url ?? content.url;
|
||||
const media = mediaFromContent(content);
|
||||
|
@ -82,7 +82,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
// there's no need of thumbnail when the content is local
|
||||
if (this.props.forExport) return null;
|
||||
|
||||
const content = this.props.mxEvent.getContent<IMediaEventContent>();
|
||||
const content = this.props.mxEvent.getContent<MediaEventContent>();
|
||||
const media = mediaFromContent(content);
|
||||
|
||||
if (media.isEncrypted && this.state.decryptedThumbnailUrl) {
|
||||
|
@ -121,7 +121,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
posterLoading: true,
|
||||
});
|
||||
|
||||
const content = this.props.mxEvent.getContent<IMediaEventContent>();
|
||||
const content = this.props.mxEvent.getContent<MediaEventContent>();
|
||||
const media = mediaFromContent(content);
|
||||
if (media.hasThumbnail) {
|
||||
const image = new Image();
|
||||
|
@ -157,7 +157,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
this.props.onHeightChanged?.();
|
||||
} else {
|
||||
logger.log("NOT preloading video");
|
||||
const content = this.props.mxEvent.getContent<IMediaEventContent>();
|
||||
const content = this.props.mxEvent.getContent<MediaEventContent>();
|
||||
|
||||
let mimetype = content?.info?.mimetype;
|
||||
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
|
||||
import { MatrixClient, ResizeMethod } from "matrix-js-sdk/src/matrix";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
import { Optional } from "matrix-events-sdk";
|
||||
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
import { IMediaEventContent, IPreparedMedia, prepEventContentAsMedia } from "./models/IMediaEventContent";
|
||||
import { IPreparedMedia, prepEventContentAsMedia } from "./models/IMediaEventContent";
|
||||
import { UserFriendlyError } from "../languageHandler";
|
||||
|
||||
// Populate this class with the details of your customisations when copying it.
|
||||
|
@ -154,11 +155,11 @@ export class Media {
|
|||
|
||||
/**
|
||||
* Creates a media object from event content.
|
||||
* @param {IMediaEventContent} content The event content.
|
||||
* @param {MediaEventContent} content The event content.
|
||||
* @param {MatrixClient} client? Optional client to use.
|
||||
* @returns {Media} The media object.
|
||||
*/
|
||||
export function mediaFromContent(content: Partial<IMediaEventContent>, client?: MatrixClient): Media {
|
||||
export function mediaFromContent(content: Partial<MediaEventContent>, client?: MatrixClient): Media {
|
||||
return new Media(prepEventContentAsMedia(content), client);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,220 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO: These types should be elsewhere.
|
||||
|
||||
import { MsgType } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { BLURHASH_FIELD } from "../../utils/image-media";
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#extensions-to-mroommessage-msgtypes
|
||||
*/
|
||||
export interface EncryptedFile {
|
||||
/**
|
||||
* The URL to the file.
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* A JSON Web Key object.
|
||||
*/
|
||||
key: {
|
||||
alg: string;
|
||||
key_ops: string[]; // eslint-disable-line camelcase
|
||||
kty: string;
|
||||
k: string;
|
||||
ext: boolean;
|
||||
};
|
||||
/**
|
||||
* The 128-bit unique counter block used by AES-CTR, encoded as unpadded base64.
|
||||
*/
|
||||
iv: string;
|
||||
/**
|
||||
* A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64.
|
||||
* Clients should support the SHA-256 hash, which uses the key sha256.
|
||||
*/
|
||||
hashes: { [alg: string]: string };
|
||||
/**
|
||||
* Version of the encrypted attachment's protocol. Must be v2.
|
||||
*/
|
||||
v: string;
|
||||
}
|
||||
|
||||
interface ThumbnailInfo {
|
||||
/**
|
||||
* The mimetype of the image, e.g. image/jpeg.
|
||||
*/
|
||||
mimetype?: string;
|
||||
/**
|
||||
* The intended display width of the image in pixels.
|
||||
* This may differ from the intrinsic dimensions of the image file.
|
||||
*/
|
||||
w?: number;
|
||||
/**
|
||||
* The intended display height of the image in pixels.
|
||||
* This may differ from the intrinsic dimensions of the image file.
|
||||
*/
|
||||
h?: number;
|
||||
/**
|
||||
* Size of the image in bytes.
|
||||
*/
|
||||
size?: number;
|
||||
}
|
||||
|
||||
interface BaseInfo {
|
||||
mimetype?: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mfile
|
||||
*/
|
||||
export interface FileInfo extends BaseInfo {
|
||||
/**
|
||||
* @see https://github.com/matrix-org/matrix-spec-proposals/pull/2448
|
||||
*/
|
||||
[BLURHASH_FIELD]?: string;
|
||||
/**
|
||||
* Information on the encrypted thumbnail file, as specified in End-to-end encryption.
|
||||
* Only present if the thumbnail is encrypted.
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#sending-encrypted-attachments
|
||||
*/
|
||||
thumbnail_file?: EncryptedFile;
|
||||
/**
|
||||
* Metadata about the image referred to in thumbnail_url.
|
||||
*/
|
||||
thumbnail_info?: ThumbnailInfo;
|
||||
/**
|
||||
* The URL to the thumbnail of the file. Only present if the thumbnail is unencrypted.
|
||||
*/
|
||||
thumbnail_url?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mimage
|
||||
*
|
||||
*/
|
||||
export interface ImageInfo extends FileInfo, ThumbnailInfo {}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mimage
|
||||
*/
|
||||
export interface AudioInfo extends BaseInfo {
|
||||
/**
|
||||
* The duration of the audio in milliseconds.
|
||||
*/
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mvideo
|
||||
*/
|
||||
export interface VideoInfo extends AudioInfo, ImageInfo {
|
||||
/**
|
||||
* The duration of the video in milliseconds.
|
||||
*/
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
export type IMediaEventInfo = FileInfo | ImageInfo | AudioInfo | VideoInfo;
|
||||
|
||||
interface BaseContent {
|
||||
/**
|
||||
* Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption.
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#sending-encrypted-attachments
|
||||
*/
|
||||
file?: EncryptedFile;
|
||||
/**
|
||||
* Required if the file is unencrypted. The URL (typically mxc:// URI) to the file.
|
||||
*/
|
||||
url?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mfile
|
||||
*/
|
||||
export interface FileContent extends BaseContent {
|
||||
/**
|
||||
* A human-readable description of the file.
|
||||
* This is recommended to be the filename of the original upload.
|
||||
*/
|
||||
body: string;
|
||||
/**
|
||||
* The original filename of the uploaded file.
|
||||
*/
|
||||
filename?: string;
|
||||
/**
|
||||
* Information about the file referred to in url.
|
||||
*/
|
||||
info?: FileInfo;
|
||||
/**
|
||||
* One of: [m.file].
|
||||
*/
|
||||
msgtype: MsgType.File;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mimage
|
||||
*/
|
||||
export interface ImageContent extends BaseContent {
|
||||
/**
|
||||
* A textual representation of the image.
|
||||
* This could be the alt text of the image, the filename of the image,
|
||||
* or some kind of content description for accessibility e.g. ‘image attachment’.
|
||||
*/
|
||||
body: string;
|
||||
/**
|
||||
* Metadata about the image referred to in url.
|
||||
*/
|
||||
info?: ImageInfo;
|
||||
/**
|
||||
* One of: [m.image].
|
||||
*/
|
||||
msgtype: MsgType.Image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#maudio
|
||||
*/
|
||||
export interface AudioContent extends BaseContent {
|
||||
/**
|
||||
* A description of the audio e.g. ‘Bee Gees - Stayin’ Alive’,
|
||||
* or some kind of content description for accessibility e.g. ‘audio attachment’.
|
||||
*/
|
||||
body: string;
|
||||
/**
|
||||
* Metadata for the audio clip referred to in url.
|
||||
*/
|
||||
info?: AudioInfo;
|
||||
/**
|
||||
* One of: [m.audio].
|
||||
*/
|
||||
msgtype: MsgType.Audio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://spec.matrix.org/v1.7/client-server-api/#mvideo
|
||||
*/
|
||||
export interface VideoContent extends BaseContent {
|
||||
/**
|
||||
* A description of the video e.g. ‘Gangnam style’,
|
||||
* or some kind of content description for accessibility e.g. ‘video attachment’.
|
||||
*/
|
||||
body: string;
|
||||
/**
|
||||
* Metadata about the video clip referred to in url.
|
||||
*/
|
||||
info?: VideoInfo;
|
||||
/**
|
||||
* One of: [m.video].
|
||||
*/
|
||||
msgtype: MsgType.Video;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type representing media event contents for `m.room.message` events listed in the Matrix specification
|
||||
*/
|
||||
export type IMediaEventContent = FileContent | ImageContent | AudioContent | VideoContent;
|
||||
import { EncryptedFile, MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
export interface IPreparedMedia extends IMediaObject {
|
||||
thumbnail?: IMediaObject;
|
||||
|
@ -241,11 +28,11 @@ export interface IMediaObject {
|
|||
/**
|
||||
* Parses an event content body into a prepared media object. This prepared media object
|
||||
* can be used with other functions to manipulate the media.
|
||||
* @param {IMediaEventContent} content Unredacted media event content. See interface.
|
||||
* @param {MediaEventContent} content Unredacted media event content. See interface.
|
||||
* @returns {IPreparedMedia} A prepared media object.
|
||||
* @throws Throws if the given content cannot be packaged into a prepared media object.
|
||||
*/
|
||||
export function prepEventContentAsMedia(content: Partial<IMediaEventContent>): IPreparedMedia {
|
||||
export function prepEventContentAsMedia(content: Partial<MediaEventContent>): IPreparedMedia {
|
||||
let thumbnail: IMediaObject | undefined;
|
||||
if (typeof content?.info === "object" && "thumbnail_url" in content.info && content.info.thumbnail_url) {
|
||||
thumbnail = {
|
||||
|
|
|
@ -15,8 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { IEventRelation, UploadProgress } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { EncryptedFile } from "../customisations/models/IMediaEventContent";
|
||||
import { EncryptedFile } from "matrix-js-sdk/src/types";
|
||||
|
||||
export class RoomUpload {
|
||||
public readonly abortController = new AbortController();
|
||||
|
|
|
@ -17,9 +17,9 @@ limitations under the License.
|
|||
// Pull in the encryption lib so that we can decrypt attachments.
|
||||
import encrypt from "matrix-encrypt-attachment";
|
||||
import { parseErrorResponse } from "matrix-js-sdk/src/matrix";
|
||||
import { EncryptedFile, MediaEventInfo } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { mediaFromContent } from "../customisations/Media";
|
||||
import { EncryptedFile, IMediaEventInfo } from "../customisations/models/IMediaEventContent";
|
||||
import { getBlobSafeMimeType } from "./blobs";
|
||||
|
||||
export class DownloadError extends Error {
|
||||
|
@ -44,10 +44,10 @@ export class DecryptError extends Error {
|
|||
* This passed to [link]{@link https://github.com/matrix-org/matrix-encrypt-attachment}
|
||||
* as the encryption info object, so will also have the those keys in addition to
|
||||
* the keys below.
|
||||
* @param {IMediaEventInfo} info The info parameter taken from the matrix event.
|
||||
* @param {MediaEventInfo} info The info parameter taken from the matrix event.
|
||||
* @returns {Promise<Blob>} Resolves to a Blob of the file.
|
||||
*/
|
||||
export async function decryptFile(file?: EncryptedFile, info?: IMediaEventInfo): Promise<Blob> {
|
||||
export async function decryptFile(file?: EncryptedFile, info?: MediaEventInfo): Promise<Blob> {
|
||||
// throws if file is falsy
|
||||
const media = mediaFromContent({ file });
|
||||
|
||||
|
|
|
@ -25,22 +25,22 @@ import {
|
|||
FileSizeReturnArray,
|
||||
FileSizeReturnObject,
|
||||
} from "filesize";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { IMediaEventContent } from "../customisations/models/IMediaEventContent";
|
||||
import { _t } from "../languageHandler";
|
||||
|
||||
/**
|
||||
* Extracts a human-readable label for the file attachment to use as
|
||||
* link text.
|
||||
*
|
||||
* @param {IMediaEventContent} content The "content" key of the matrix event.
|
||||
* @param {MediaEventContent} content The "content" key of the matrix event.
|
||||
* @param {string} fallbackText The fallback text
|
||||
* @param {boolean} withSize Whether to include size information. Default true.
|
||||
* @param {boolean} shortened Ensure the extension of the file name is visible. Default false.
|
||||
* @return {string} the human-readable link text for the attachment.
|
||||
*/
|
||||
export function presentableTextForFile(
|
||||
content: IMediaEventContent,
|
||||
content: MediaEventContent,
|
||||
fallbackText = _t("common|attachment"),
|
||||
withSize = true,
|
||||
shortened = false,
|
||||
|
|
|
@ -15,12 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { MatrixEvent, EventType, MsgType } from "matrix-js-sdk/src/matrix";
|
||||
import { FileContent, ImageContent, MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { LazyValue } from "./LazyValue";
|
||||
import { Media, mediaFromContent } from "../customisations/Media";
|
||||
import { decryptFile } from "./DecryptFile";
|
||||
import { FileContent, ImageContent, IMediaEventContent } from "../customisations/models/IMediaEventContent";
|
||||
import { IDestroyable } from "./IDestroyable";
|
||||
|
||||
// TODO: We should consider caching the blobs. https://github.com/vector-im/element-web/issues/17192
|
||||
|
@ -48,7 +48,7 @@ export class MediaEventHelper implements IDestroyable {
|
|||
public get fileName(): string {
|
||||
return (
|
||||
this.event.getContent<FileContent>().filename ||
|
||||
this.event.getContent<IMediaEventContent>().body ||
|
||||
this.event.getContent<MediaEventContent>().body ||
|
||||
"download"
|
||||
);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ export class MediaEventHelper implements IDestroyable {
|
|||
|
||||
private fetchSource = (): Promise<Blob> => {
|
||||
if (this.media.isEncrypted) {
|
||||
const content = this.event.getContent<IMediaEventContent>();
|
||||
const content = this.event.getContent<MediaEventContent>();
|
||||
return decryptFile(content.file!, content.info);
|
||||
}
|
||||
return this.media.downloadSource().then((r) => r.blob());
|
||||
|
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { Direction, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { MediaEventContent } from "matrix-js-sdk/src/types";
|
||||
import { saveAs } from "file-saver";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import sanitizeFilename from "sanitize-filename";
|
||||
|
@ -24,7 +25,6 @@ import { decryptFile } from "../DecryptFile";
|
|||
import { mediaFromContent } from "../../customisations/Media";
|
||||
import { formatFullDateNoDay, formatFullDateNoDayISO } from "../../DateUtils";
|
||||
import { isVoiceMessage } from "../EventUtils";
|
||||
import { IMediaEventContent } from "../../customisations/models/IMediaEventContent";
|
||||
import { _t } from "../../languageHandler";
|
||||
import SdkConfig from "../../SdkConfig";
|
||||
|
||||
|
@ -225,7 +225,7 @@ export default abstract class Exporter {
|
|||
let blob: Blob | undefined = undefined;
|
||||
try {
|
||||
const isEncrypted = event.isEncrypted();
|
||||
const content = event.getContent<IMediaEventContent>();
|
||||
const content = event.getContent<MediaEventContent>();
|
||||
const shouldDecrypt = isEncrypted && content.hasOwnProperty("file") && event.getType() !== "m.sticker";
|
||||
if (shouldDecrypt) {
|
||||
blob = await decryptFile(content.file);
|
||||
|
|
|
@ -14,8 +14,9 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { EncryptedFile } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { BlurhashEncoder } from "../BlurhashEncoder";
|
||||
import { EncryptedFile } from "../customisations/models/IMediaEventContent";
|
||||
|
||||
type ThumbnailableElement = HTMLImageElement | HTMLVideoElement;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
RelationType,
|
||||
TypedEventEmitter,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { EncryptedFile } from "matrix-js-sdk/src/types";
|
||||
|
||||
import {
|
||||
ChunkRecordedPayload,
|
||||
|
@ -38,7 +39,6 @@ import {
|
|||
VoiceBroadcastRecorderEvent,
|
||||
} from "..";
|
||||
import { uploadFile } from "../../ContentMessages";
|
||||
import { EncryptedFile } from "../../customisations/models/IMediaEventContent";
|
||||
import { createVoiceMessageContent } from "../../utils/createVoiceMessageContent";
|
||||
import { IDestroyable } from "../../utils/IDestroyable";
|
||||
import dis from "../../dispatcher/dispatcher";
|
||||
|
|
|
@ -29,9 +29,9 @@ import {
|
|||
Relations,
|
||||
SyncState,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { EncryptedFile } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { uploadFile } from "../../../src/ContentMessages";
|
||||
import { EncryptedFile } from "../../../src/customisations/models/IMediaEventContent";
|
||||
import { createVoiceMessageContent } from "../../../src/utils/createVoiceMessageContent";
|
||||
import {
|
||||
createVoiceBroadcastRecorder,
|
||||
|
|
Loading…
Reference in a new issue