diff --git a/src/app/components/RenderMessageContent.tsx b/src/app/components/RenderMessageContent.tsx
index 55b0ffc2..0c37f322 100644
--- a/src/app/components/RenderMessageContent.tsx
+++ b/src/app/components/RenderMessageContent.tsx
@@ -29,7 +29,7 @@ import { ImageViewer } from './image-viewer';
import { PdfViewer } from './Pdf-viewer';
import { TextViewer } from './text-viewer';
import { testMatrixTo } from '../plugins/matrix-to';
-import {IImageContent} from "../../types/matrix/common";
+import { IImageContent } from '../../types/matrix/common';
type RenderMessageContentProps = {
displayName: string;
@@ -70,7 +70,7 @@ export function RenderMessageContent({
};
const renderCaption = () => {
const content: IImageContent = getContent();
- if(content.filename && content.filename !== content.body) {
+ if (content.filename && content.filename !== content.body) {
return (
- )
+ );
}
return null;
- }
+ };
const renderFile = () => (
<>
(
- (
- }
- />
- )}
- renderAsTextFile={() => (
- }
- />
- )}
- >
-
-
-
+ (
+ }
+ />
+ )}
+ renderAsTextFile={() => (
+ }
+ />
+ )}
+ >
+
+
)}
outlined={outlineAttachment}
/>
@@ -188,12 +187,12 @@ export function RenderMessageContent({
(
- }
- renderViewer={(p) => }
- />
+ }
+ renderViewer={(p) => }
+ />
)}
outlined={outlineAttachment}
/>
@@ -208,23 +207,21 @@ export function RenderMessageContent({
(
+ renderVideoContent={({ body, info, ...props }) => (
(
- (
-
- )}
- />
- )
+ (
+
+ )}
+ />
+ )
: undefined
}
renderVideo={(p) => }
@@ -234,7 +231,6 @@ export function RenderMessageContent({
/>
{renderCaption()}
>
-
);
}
@@ -251,7 +247,6 @@ export function RenderMessageContent({
/>
{renderCaption()}
>
-
);
}
diff --git a/src/app/components/message/MsgTypeRenderers.tsx b/src/app/components/message/MsgTypeRenderers.tsx
index 287a5ca4..07ad3a74 100644
--- a/src/app/components/message/MsgTypeRenderers.tsx
+++ b/src/app/components/message/MsgTypeRenderers.tsx
@@ -222,6 +222,8 @@ type RenderVideoContentProps = {
mimeType: string;
url: string;
encInfo?: IEncryptedFile;
+ markedAsSpoiler?: boolean;
+ spoilerReason?: string;
};
type MVideoProps = {
content: IVideoContent;
@@ -256,6 +258,8 @@ export function MVideo({ content, renderAsFile, renderVideoContent, outlined }:
mimeType: safeMimeType,
url: mxcUrl,
encInfo: content.file,
+ markedAsSpoiler: content[MATRIX_SPOILER_PROPERTY_NAME],
+ spoilerReason: content[MATRIX_SPOILER_REASON_PROPERTY_NAME],
})}
diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx
index f6ddbb5a..748714b1 100644
--- a/src/app/components/message/content/VideoContent.tsx
+++ b/src/app/components/message/content/VideoContent.tsx
@@ -3,6 +3,7 @@ import {
Badge,
Box,
Button,
+ Chip,
Icon,
Icons,
Spinner,
@@ -47,6 +48,8 @@ type VideoContentProps = {
info: IVideoInfo & IThumbnailContent;
encInfo?: EncryptedAttachmentInfo;
autoPlay?: boolean;
+ markedAsSpoiler?: boolean;
+ spoilerReason?: string;
renderThumbnail?: () => ReactNode;
renderVideo: (props: RenderVideoProps) => ReactNode;
};
@@ -60,6 +63,8 @@ export const VideoContent = as<'div', VideoContentProps>(
info,
encInfo,
autoPlay,
+ markedAsSpoiler,
+ spoilerReason,
renderThumbnail,
renderVideo,
...props
@@ -72,6 +77,7 @@ export const VideoContent = as<'div', VideoContentProps>(
const [load, setLoad] = useState(false);
const [error, setError] = useState(false);
+ const [blurred, setBlurred] = useState(markedAsSpoiler ?? false);
const [srcState, loadSrc] = useAsyncCallback(
useCallback(async () => {
@@ -114,11 +120,15 @@ export const VideoContent = as<'div', VideoContentProps>(
/>
)}
{renderThumbnail && !load && (
-
+
{renderThumbnail()}
)}
- {!autoPlay && srcState.status === AsyncStatus.Idle && (
+ {!autoPlay && !blurred && srcState.status === AsyncStatus.Idle && (
)}
{srcState.status === AsyncStatus.Success && (
-
+
{renderVideo({
title: body,
src: srcState.data,
@@ -144,8 +154,39 @@ export const VideoContent = as<'div', VideoContentProps>(
})}
)}
+ {blurred && !error && srcState.status !== AsyncStatus.Error && (
+
+
+ {spoilerReason}
+
+ )
+ }
+ position="Top"
+ align="Center"
+ >
+ {(triggerRef) => (
+ {
+ setBlurred(false);
+ }}
+ >
+ Spoiler
+
+ )}
+
+
+ )}
{(srcState.status === AsyncStatus.Loading || srcState.status === AsyncStatus.Success) &&
- !load && (
+ !load &&
+ !markedAsSpoiler && (
diff --git a/src/app/components/upload-card/UploadCardRenderer.tsx b/src/app/components/upload-card/UploadCardRenderer.tsx
index 4cc8a00c..bad13561 100644
--- a/src/app/components/upload-card/UploadCardRenderer.tsx
+++ b/src/app/components/upload-card/UploadCardRenderer.tsx
@@ -66,7 +66,7 @@ export function UploadCardRenderer({
Retry
)}
- {file.type.startsWith('image') && (
+ {(file.type.startsWith('image') || file.type.startsWith('video')) && (
diff --git a/src/app/features/room/msgContent.ts b/src/app/features/room/msgContent.ts
index bc660f2c..5b7cd145 100644
--- a/src/app/features/room/msgContent.ts
+++ b/src/app/features/room/msgContent.ts
@@ -82,7 +82,7 @@ export const getVideoMsgContent = async (
item: TUploadItem,
mxc: string
): Promise => {
- const { file, originalFile, encInfo } = item;
+ const { file, originalFile, encInfo, metadata } = item;
const [videoError, videoEl] = await to(loadVideoElement(getVideoFileUrl(originalFile)));
if (videoError) console.warn(videoError);
@@ -91,6 +91,7 @@ export const getVideoMsgContent = async (
msgtype: MsgType.Video,
filename: file.name,
body: file.name,
+ [MATRIX_SPOILER_PROPERTY_NAME]: metadata.markedAsSpoiler,
};
if (videoEl) {
const [thumbError, thumbContent] = await to(