diff --git a/src/app/components/ClientConfigLoader.tsx b/src/app/components/ClientConfigLoader.tsx index 769b9f2c7..f2fca4b9d 100644 --- a/src/app/components/ClientConfigLoader.tsx +++ b/src/app/components/ClientConfigLoader.tsx @@ -21,7 +21,7 @@ export function ClientConfigLoader({ fallback, error, children }: ClientConfigLo const ignoreCallback = useCallback(() => setIgnoreError(true), []); useEffect(() => { - void load().catch(() => undefined); + load().catch(() => undefined); }, [load]); if (state.status === AsyncStatus.Idle || state.status === AsyncStatus.Loading) { diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index 0b25aca23..575682b36 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -113,7 +113,7 @@ export const ImageContent = as<'div', ImageContentProps>( }; useEffect(() => { - if (autoPlay) void loadSrc().catch(() => undefined); + if (autoPlay) loadSrc().catch(() => undefined); }, [autoPlay, loadSrc]); return ( diff --git a/src/app/components/message/content/ThumbnailContent.tsx b/src/app/components/message/content/ThumbnailContent.tsx index 984e3f68b..efe7774ef 100644 --- a/src/app/components/message/content/ThumbnailContent.tsx +++ b/src/app/components/message/content/ThumbnailContent.tsx @@ -37,7 +37,7 @@ export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) { ); useEffect(() => { - void loadThumbSrc().catch(() => undefined); + loadThumbSrc().catch(() => undefined); }, [loadThumbSrc]); return thumbSrcState.status === AsyncStatus.Success ? renderImage(thumbSrcState.data) : null; diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx index 91c6efc68..e63625087 100644 --- a/src/app/components/message/content/VideoContent.tsx +++ b/src/app/components/message/content/VideoContent.tsx @@ -106,7 +106,7 @@ export const VideoContent = as<'div', VideoContentProps>( }; useEffect(() => { - if (autoPlay) void loadSrc().catch(() => undefined); + if (autoPlay) loadSrc().catch(() => undefined); }, [autoPlay, loadSrc]); return ( diff --git a/src/app/features/room/message/EditHistoryModal.tsx b/src/app/features/room/message/EditHistoryModal.tsx index 9a00493de..e5ccb5f94 100644 --- a/src/app/features/room/message/EditHistoryModal.tsx +++ b/src/app/features/room/message/EditHistoryModal.tsx @@ -1,4 +1,6 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { ReactNode, useCallback, useEffect } from 'react'; +import parse from 'html-react-parser'; +import Linkify from 'linkify-react'; import FocusTrap from 'focus-trap-react'; import { Box, @@ -18,6 +20,8 @@ import { import { MatrixEvent, Room } from 'matrix-js-sdk'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { stopPropagation } from '../../../utils/keyboard'; +import { sanitizeCustomHtml } from '../../../utils/sanitize'; +import { LINKIFY_OPTS } from '../../../plugins/react-custom-html-parser'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { timeDayMonYear, timeHourMinute } from '../../../utils/time'; import { useSetting } from '../../../state/hooks/settings'; @@ -52,17 +56,24 @@ function isRawEditEvent(raw: unknown): raw is RawEditEvent { return typeof r.event_id === 'string' && typeof r.origin_server_ts === 'number'; } -function getVersionBody(evt: MatrixEvent): string { +function getVersionContent(evt: MatrixEvent): ReactNode { const content = evt.getContent(); const newContent = content['m.new_content'] as Record | undefined; const source = newContent ?? content; + const format = source.format; const formattedBody = source.formatted_body; - if (typeof formattedBody === 'string') { - return formattedBody.replace(/<[^>]+>/g, '').trim() || '(no text)'; + if ( + format === 'org.matrix.custom.html' && + typeof formattedBody === 'string' && + formattedBody.trim() + ) { + return parse(sanitizeCustomHtml(formattedBody)); } + const body = source.body; - return typeof body === 'string' ? body : '(no text)'; + const text = typeof body === 'string' ? body : '(no text)'; + return {text}; } export function EditHistoryModal({ room, mEvent, onClose }: EditHistoryModalProps) { @@ -106,7 +117,7 @@ export function EditHistoryModal({ room, mEvent, onClose }: EditHistoryModalProp ); useEffect(() => { - void fetchHistory().catch(() => undefined); + fetchHistory().catch(() => undefined); }, [fetchHistory]); const formatTs = (ts: number): string => { @@ -115,11 +126,7 @@ export function EditHistoryModal({ room, mEvent, onClose }: EditHistoryModalProp return `${date} at ${time}`; }; - const originalBody = (() => { - const content = mEvent.getContent(); - const body = content.body; - return typeof body === 'string' ? body : '(no text)'; - })(); + const originalContent = getVersionContent(mEvent); const originalTs = mEvent.getTs(); @@ -189,7 +196,7 @@ export function EditHistoryModal({ room, mEvent, onClose }: EditHistoryModalProp - {originalBody} + {originalContent} @@ -209,7 +216,7 @@ export function EditHistoryModal({ room, mEvent, onClose }: EditHistoryModalProp size="T300" style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }} > - {getVersionBody(editEvt)} + {getVersionContent(editEvt)} ))} diff --git a/src/app/hooks/useAsyncCallback.ts b/src/app/hooks/useAsyncCallback.ts index 11d812ebe..8deed66c2 100644 --- a/src/app/hooks/useAsyncCallback.ts +++ b/src/app/hooks/useAsyncCallback.ts @@ -114,7 +114,7 @@ export const useAsyncCallbackValue = ( const [state, load] = useAsyncCallback(asyncCallback); useEffect(() => { - void load().catch(() => undefined); + load().catch(() => undefined); }, [load]); return [state, load];