mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-01-15 02:55:39 +00:00
Render captions to m.file, m.image, m.video, and m.audio (#2059)
Some checks failed
Deploy to Netlify (dev) / Deploy to Netlify (push) Has been cancelled
Some checks failed
Deploy to Netlify (dev) / Deploy to Netlify (push) Has been cancelled
* Add rendering image captions * Handle sending captions for images * Fix caption rendering on m.video and m.audio too * Remove unused renderBody() parameter * Fix m.file rendering body instead of filename where possible * Add caption rendering for generic files + Fix video and audio not properly sending captions * Use m.text for captions & render on demand * Allow custom HTML in sending captions * Don't *send* captions * mvoe content const into renderCaption() --------- Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com>
This commit is contained in:
parent
3c5afaf33a
commit
02437a6a20
|
@ -29,6 +29,7 @@ import { ImageViewer } from './image-viewer';
|
||||||
import { PdfViewer } from './Pdf-viewer';
|
import { PdfViewer } from './Pdf-viewer';
|
||||||
import { TextViewer } from './text-viewer';
|
import { TextViewer } from './text-viewer';
|
||||||
import { testMatrixTo } from '../plugins/matrix-to';
|
import { testMatrixTo } from '../plugins/matrix-to';
|
||||||
|
import {IImageContent} from "../../types/matrix/common";
|
||||||
|
|
||||||
type RenderMessageContentProps = {
|
type RenderMessageContentProps = {
|
||||||
displayName: string;
|
displayName: string;
|
||||||
|
@ -67,38 +68,63 @@ export function RenderMessageContent({
|
||||||
</UrlPreviewHolder>
|
</UrlPreviewHolder>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
const renderCaption = () => {
|
||||||
|
const content: IImageContent = getContent();
|
||||||
|
if(content.filename && content.filename !== content.body) {
|
||||||
|
return (
|
||||||
|
<MText
|
||||||
|
edited={edited}
|
||||||
|
content={content}
|
||||||
|
renderBody={(props) => (
|
||||||
|
<RenderBody
|
||||||
|
{...props}
|
||||||
|
highlightRegex={highlightRegex}
|
||||||
|
htmlReactParserOptions={htmlReactParserOptions}
|
||||||
|
linkifyOpts={linkifyOpts}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
renderUrlsPreview={urlPreview ? renderUrlsPreview : undefined}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const renderFile = () => (
|
const renderFile = () => (
|
||||||
<MFile
|
<>
|
||||||
content={getContent()}
|
<MFile
|
||||||
renderFileContent={({ body, mimeType, info, encInfo, url }) => (
|
content={getContent()}
|
||||||
<FileContent
|
renderFileContent={({ body, mimeType, info, encInfo, url }) => (
|
||||||
body={body}
|
<FileContent
|
||||||
mimeType={mimeType}
|
|
||||||
renderAsPdfFile={() => (
|
|
||||||
<ReadPdfFile
|
|
||||||
body={body}
|
body={body}
|
||||||
mimeType={mimeType}
|
mimeType={mimeType}
|
||||||
url={url}
|
renderAsPdfFile={() => (
|
||||||
encInfo={encInfo}
|
<ReadPdfFile
|
||||||
renderViewer={(p) => <PdfViewer {...p} />}
|
body={body}
|
||||||
/>
|
mimeType={mimeType}
|
||||||
)}
|
url={url}
|
||||||
renderAsTextFile={() => (
|
encInfo={encInfo}
|
||||||
<ReadTextFile
|
renderViewer={(p) => <PdfViewer {...p} />}
|
||||||
body={body}
|
/>
|
||||||
mimeType={mimeType}
|
)}
|
||||||
url={url}
|
renderAsTextFile={() => (
|
||||||
encInfo={encInfo}
|
<ReadTextFile
|
||||||
renderViewer={(p) => <TextViewer {...p} />}
|
body={body}
|
||||||
/>
|
mimeType={mimeType}
|
||||||
)}
|
url={url}
|
||||||
>
|
encInfo={encInfo}
|
||||||
<DownloadFile body={body} mimeType={mimeType} url={url} encInfo={encInfo} info={info} />
|
renderViewer={(p) => <TextViewer {...p} />}
|
||||||
</FileContent>
|
/>
|
||||||
)}
|
)}
|
||||||
outlined={outlineAttachment}
|
>
|
||||||
/>
|
<DownloadFile body={body} mimeType={mimeType} url={url} encInfo={encInfo} info={info} />
|
||||||
|
</FileContent>
|
||||||
|
|
||||||
|
)}
|
||||||
|
outlined={outlineAttachment}
|
||||||
|
/>
|
||||||
|
{renderCaption()}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (msgType === MsgType.Text) {
|
if (msgType === MsgType.Text) {
|
||||||
|
@ -158,36 +184,40 @@ export function RenderMessageContent({
|
||||||
|
|
||||||
if (msgType === MsgType.Image) {
|
if (msgType === MsgType.Image) {
|
||||||
return (
|
return (
|
||||||
<MImage
|
<>
|
||||||
content={getContent()}
|
<MImage
|
||||||
renderImageContent={(props) => (
|
content={getContent()}
|
||||||
<ImageContent
|
renderImageContent={(props) => (
|
||||||
{...props}
|
<ImageContent
|
||||||
autoPlay={mediaAutoLoad}
|
{...props}
|
||||||
renderImage={(p) => <Image {...p} loading="lazy" />}
|
autoPlay={mediaAutoLoad}
|
||||||
renderViewer={(p) => <ImageViewer {...p} />}
|
renderImage={(p) => <Image {...p} loading="lazy" />}
|
||||||
/>
|
renderViewer={(p) => <ImageViewer {...p} />}
|
||||||
)}
|
/>
|
||||||
outlined={outlineAttachment}
|
)}
|
||||||
/>
|
outlined={outlineAttachment}
|
||||||
|
/>
|
||||||
|
{renderCaption()}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgType === MsgType.Video) {
|
if (msgType === MsgType.Video) {
|
||||||
return (
|
return (
|
||||||
<MVideo
|
<>
|
||||||
content={getContent()}
|
<MVideo
|
||||||
renderAsFile={renderFile}
|
content={getContent()}
|
||||||
renderVideoContent={({ body, info, mimeType, url, encInfo }) => (
|
renderAsFile={renderFile}
|
||||||
<VideoContent
|
renderVideoContent={({ body, info, mimeType, url, encInfo }) => (
|
||||||
body={body}
|
<VideoContent
|
||||||
info={info}
|
body={body}
|
||||||
mimeType={mimeType}
|
info={info}
|
||||||
url={url}
|
mimeType={mimeType}
|
||||||
encInfo={encInfo}
|
url={url}
|
||||||
renderThumbnail={
|
encInfo={encInfo}
|
||||||
mediaAutoLoad
|
renderThumbnail={
|
||||||
? () => (
|
mediaAutoLoad
|
||||||
|
? () => (
|
||||||
<ThumbnailContent
|
<ThumbnailContent
|
||||||
info={info}
|
info={info}
|
||||||
renderImage={(src) => (
|
renderImage={(src) => (
|
||||||
|
@ -195,26 +225,33 @@ export function RenderMessageContent({
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
renderVideo={(p) => <Video {...p} />}
|
renderVideo={(p) => <Video {...p} />}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
outlined={outlineAttachment}
|
outlined={outlineAttachment}
|
||||||
/>
|
/>
|
||||||
|
{renderCaption()}
|
||||||
|
</>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgType === MsgType.Audio) {
|
if (msgType === MsgType.Audio) {
|
||||||
return (
|
return (
|
||||||
<MAudio
|
<>
|
||||||
content={getContent()}
|
<MAudio
|
||||||
renderAsFile={renderFile}
|
content={getContent()}
|
||||||
renderAudioContent={(props) => (
|
renderAsFile={renderFile}
|
||||||
<AudioContent {...props} renderMediaControl={(p) => <MediaControl {...p} />} />
|
renderAudioContent={(props) => (
|
||||||
)}
|
<AudioContent {...props} renderMediaControl={(p) => <MediaControl {...p} />} />
|
||||||
outlined={outlineAttachment}
|
)}
|
||||||
/>
|
outlined={outlineAttachment}
|
||||||
|
/>
|
||||||
|
{renderCaption()}
|
||||||
|
</>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,7 @@ export function MNotice({ edited, content, renderBody, renderUrlsPreview }: MNot
|
||||||
|
|
||||||
type RenderImageContentProps = {
|
type RenderImageContentProps = {
|
||||||
body: string;
|
body: string;
|
||||||
|
filename?: string;
|
||||||
info?: IImageInfo & IThumbnailContent;
|
info?: IImageInfo & IThumbnailContent;
|
||||||
mimeType?: string;
|
mimeType?: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -282,7 +283,7 @@ export function MAudio({ content, renderAsFile, renderAudioContent, outlined }:
|
||||||
return (
|
return (
|
||||||
<Attachment outlined={outlined}>
|
<Attachment outlined={outlined}>
|
||||||
<AttachmentHeader>
|
<AttachmentHeader>
|
||||||
<FileHeader body={content.body ?? 'Audio'} mimeType={safeMimeType} />
|
<FileHeader body={content.filename ?? content.body ?? 'Audio'} mimeType={safeMimeType} />
|
||||||
</AttachmentHeader>
|
</AttachmentHeader>
|
||||||
<AttachmentBox>
|
<AttachmentBox>
|
||||||
<AttachmentContent>
|
<AttachmentContent>
|
||||||
|
@ -322,14 +323,14 @@ export function MFile({ content, renderFileContent, outlined }: MFileProps) {
|
||||||
<Attachment outlined={outlined}>
|
<Attachment outlined={outlined}>
|
||||||
<AttachmentHeader>
|
<AttachmentHeader>
|
||||||
<FileHeader
|
<FileHeader
|
||||||
body={content.body ?? 'Unnamed File'}
|
body={content.filename ?? content.body ?? 'Unnamed File'}
|
||||||
mimeType={fileInfo?.mimetype ?? FALLBACK_MIMETYPE}
|
mimeType={fileInfo?.mimetype ?? FALLBACK_MIMETYPE}
|
||||||
/>
|
/>
|
||||||
</AttachmentHeader>
|
</AttachmentHeader>
|
||||||
<AttachmentBox>
|
<AttachmentBox>
|
||||||
<AttachmentContent>
|
<AttachmentContent>
|
||||||
{renderFileContent({
|
{renderFileContent({
|
||||||
body: content.body ?? 'File',
|
body: content.filename ?? content.body ?? 'File',
|
||||||
info: fileInfo ?? {},
|
info: fileInfo ?? {},
|
||||||
mimeType: fileInfo?.mimetype ?? FALLBACK_MIMETYPE,
|
mimeType: fileInfo?.mimetype ?? FALLBACK_MIMETYPE,
|
||||||
url: mxcUrl,
|
url: mxcUrl,
|
||||||
|
|
|
@ -42,7 +42,7 @@ const generateThumbnailContent = async (
|
||||||
export const getImageMsgContent = async (
|
export const getImageMsgContent = async (
|
||||||
mx: MatrixClient,
|
mx: MatrixClient,
|
||||||
item: TUploadItem,
|
item: TUploadItem,
|
||||||
mxc: string
|
mxc: string,
|
||||||
): Promise<IContent> => {
|
): Promise<IContent> => {
|
||||||
const { file, originalFile, encInfo } = item;
|
const { file, originalFile, encInfo } = item;
|
||||||
const [imgError, imgEl] = await to(loadImageElement(getImageFileUrl(originalFile)));
|
const [imgError, imgEl] = await to(loadImageElement(getImageFileUrl(originalFile)));
|
||||||
|
@ -50,6 +50,7 @@ export const getImageMsgContent = async (
|
||||||
|
|
||||||
const content: IContent = {
|
const content: IContent = {
|
||||||
msgtype: MsgType.Image,
|
msgtype: MsgType.Image,
|
||||||
|
filename: file.name,
|
||||||
body: file.name,
|
body: file.name,
|
||||||
};
|
};
|
||||||
if (imgEl) {
|
if (imgEl) {
|
||||||
|
@ -74,7 +75,7 @@ export const getImageMsgContent = async (
|
||||||
export const getVideoMsgContent = async (
|
export const getVideoMsgContent = async (
|
||||||
mx: MatrixClient,
|
mx: MatrixClient,
|
||||||
item: TUploadItem,
|
item: TUploadItem,
|
||||||
mxc: string
|
mxc: string,
|
||||||
): Promise<IContent> => {
|
): Promise<IContent> => {
|
||||||
const { file, originalFile, encInfo } = item;
|
const { file, originalFile, encInfo } = item;
|
||||||
|
|
||||||
|
@ -83,6 +84,7 @@ export const getVideoMsgContent = async (
|
||||||
|
|
||||||
const content: IContent = {
|
const content: IContent = {
|
||||||
msgtype: MsgType.Video,
|
msgtype: MsgType.Video,
|
||||||
|
filename: file.name,
|
||||||
body: file.name,
|
body: file.name,
|
||||||
};
|
};
|
||||||
if (videoEl) {
|
if (videoEl) {
|
||||||
|
@ -122,6 +124,7 @@ export const getAudioMsgContent = (item: TUploadItem, mxc: string): IContent =>
|
||||||
const { file, encInfo } = item;
|
const { file, encInfo } = item;
|
||||||
const content: IContent = {
|
const content: IContent = {
|
||||||
msgtype: MsgType.Audio,
|
msgtype: MsgType.Audio,
|
||||||
|
filename: file.name,
|
||||||
body: file.name,
|
body: file.name,
|
||||||
info: {
|
info: {
|
||||||
mimetype: file.type,
|
mimetype: file.type,
|
||||||
|
|
|
@ -43,6 +43,7 @@ export type IThumbnailContent = {
|
||||||
export type IImageContent = {
|
export type IImageContent = {
|
||||||
msgtype: MsgType.Image;
|
msgtype: MsgType.Image;
|
||||||
body?: string;
|
body?: string;
|
||||||
|
filename?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
info?: IImageInfo & IThumbnailContent;
|
info?: IImageInfo & IThumbnailContent;
|
||||||
file?: IEncryptedFile;
|
file?: IEncryptedFile;
|
||||||
|
@ -51,6 +52,7 @@ export type IImageContent = {
|
||||||
export type IVideoContent = {
|
export type IVideoContent = {
|
||||||
msgtype: MsgType.Video;
|
msgtype: MsgType.Video;
|
||||||
body?: string;
|
body?: string;
|
||||||
|
filename?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
info?: IVideoInfo & IThumbnailContent;
|
info?: IVideoInfo & IThumbnailContent;
|
||||||
file?: IEncryptedFile;
|
file?: IEncryptedFile;
|
||||||
|
@ -59,6 +61,7 @@ export type IVideoContent = {
|
||||||
export type IAudioContent = {
|
export type IAudioContent = {
|
||||||
msgtype: MsgType.Audio;
|
msgtype: MsgType.Audio;
|
||||||
body?: string;
|
body?: string;
|
||||||
|
filename?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
info?: IAudioInfo;
|
info?: IAudioInfo;
|
||||||
file?: IEncryptedFile;
|
file?: IEncryptedFile;
|
||||||
|
@ -67,6 +70,7 @@ export type IAudioContent = {
|
||||||
export type IFileContent = {
|
export type IFileContent = {
|
||||||
msgtype: MsgType.File;
|
msgtype: MsgType.File;
|
||||||
body?: string;
|
body?: string;
|
||||||
|
filename?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
info?: IFileInfo & IThumbnailContent;
|
info?: IFileInfo & IThumbnailContent;
|
||||||
file?: IEncryptedFile;
|
file?: IEncryptedFile;
|
||||||
|
|
Loading…
Reference in a new issue