Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Reuse media content/info types from the js-sdk #12308

Merged
merged 4 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/**",
Expand Down
27 changes: 27 additions & 0 deletions src/@types/matrix-js-sdk.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
18 changes: 9 additions & 9 deletions src/ContentMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/components/views/messages/MAudioBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/components/views/messages/MFileBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ 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";
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";
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/messages/MImageBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/messages/MImageReplyBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/components/views/messages/MStickerBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}
10 changes: 5 additions & 5 deletions src/components/views/messages/MVideoBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ 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";
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";
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;

Expand Down
7 changes: 4 additions & 3 deletions src/customisations/Media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}

Expand Down
Loading
Loading