From ac0fb82339fc580da9db60c183a39d72e6fba3ea Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 12 Jul 2022 15:34:57 +0300 Subject: Add support for rendering captions in media messages --- src/components/views/messages/IBodyProps.ts | 2 ++ src/components/views/messages/MessageEvent.tsx | 15 +++++++++++++++ src/components/views/messages/TextualBody.tsx | 11 +++++++++++ src/utils/FileUtils.ts | 4 +++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/IBodyProps.ts b/src/components/views/messages/IBodyProps.ts index e48ba96b56..3caeff225c 100644 --- a/src/components/views/messages/IBodyProps.ts +++ b/src/components/views/messages/IBodyProps.ts @@ -51,4 +51,6 @@ export interface IBodyProps { // Set to `true` to disable interactions (e.g. video controls) and to remove controls from the tab order. // This may be useful when displaying a preview of the event. inhibitInteraction?: boolean; + + OrigBodyType?: React.ComponentType>; } diff --git a/src/components/views/messages/MessageEvent.tsx b/src/components/views/messages/MessageEvent.tsx index 1a5d09e415..bfe908aacc 100644 --- a/src/components/views/messages/MessageEvent.tsx +++ b/src/components/views/messages/MessageEvent.tsx @@ -175,6 +175,15 @@ export default class MessageEvent extends React.Component implements IMe } } + // @ts-ignore + const hasCaption = [MsgType.Image, MsgType.File, MsgType.Audio, MsgType.Video].includes(msgtype) + && content.filename && content.filename !== content.body; + let OrigBodyType; + if (hasCaption) { + OrigBodyType = BodyType + BodyType = CaptionBody + } + if (SettingsStore.getValue("feature_mjolnir")) { const key = `mx_mjolnir_render_${this.props.mxEvent.getRoomId()}__${this.props.mxEvent.getId()}`; const allowRender = localStorage.getItem(key) === "true"; @@ -208,7 +217,13 @@ export default class MessageEvent extends React.Component implements IMe getRelationsForEvent={this.props.getRelationsForEvent} isSeeingThroughMessageHiddenForModeration={this.props.isSeeingThroughMessageHiddenForModeration} inhibitInteraction={this.props.inhibitInteraction} + OrigBodyType={OrigBodyType} /> ) : null; } } + +const CaptionBody: React.FunctionComponent>}> = ({OrigBodyType, ...props}) => (
+ + +
) diff --git a/src/components/views/messages/TextualBody.tsx b/src/components/views/messages/TextualBody.tsx index 8b7bfb9a5a..a8890303f8 100644 --- a/src/components/views/messages/TextualBody.tsx +++ b/src/components/views/messages/TextualBody.tsx @@ -557,6 +557,9 @@ export default class TextualBody extends React.Component { const isNotice = content.msgtype === MsgType.Notice; const isEmote = content.msgtype === MsgType.Emote; + // @ts-ignore + const isCaption = [MsgType.Image, MsgType.File, MsgType.Audio, MsgType.Video].includes(content.msgtype); + const willHaveWrapper = this.props.replacingEventId || this.props.isSeeingThroughMessageHiddenForModeration || isEmote; @@ -635,6 +638,14 @@ export default class TextualBody extends React.Component { ); } + if (isCaption) { + return ( +
+ { body } + { widgets } +
+ ); + } return (
{body} diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts index 194cb31d20..0c0aec2138 100644 --- a/src/utils/FileUtils.ts +++ b/src/utils/FileUtils.ts @@ -38,7 +38,9 @@ export function presentableTextForFile( shortened = false, ): string { let text = fallbackText; - if (content.body?.length) { + if (content.filename?.length) { + text = content.filename + } else if (content.body?.length) { // The content body should be the name of the file including a // file extension. text = content.body; -- 2.47.0