Apply media visible hook to inline images.
This commit is contained in:
@@ -22,7 +22,7 @@ import { getEmojiFromUnicode } from "@matrix-org/emojibase-bindings";
|
||||
import SettingsStore from "./settings/SettingsStore";
|
||||
import { stripHTMLReply, stripPlainReply } from "./utils/Reply";
|
||||
import { PERMITTED_URL_SCHEMES } from "./utils/UrlUtils";
|
||||
import { sanitizeHtmlParams, transformTags } from "./Linkify";
|
||||
import { filterImg, sanitizeHtmlParams, transformTags } from "./Linkify";
|
||||
import { graphemeSegmenter } from "./utils/strings";
|
||||
|
||||
export { Linkify, linkifyAndSanitizeHtml } from "./Linkify";
|
||||
@@ -294,6 +294,7 @@ export interface EventRenderOpts {
|
||||
disableBigEmoji?: boolean;
|
||||
stripReplyFallback?: boolean;
|
||||
forComposerQuote?: boolean;
|
||||
mediaIsVisible?: boolean;
|
||||
}
|
||||
|
||||
function analyseEvent(content: IContent, highlights: Optional<string[]>, opts: EventRenderOpts = {}): EventAnalysis {
|
||||
@@ -301,6 +302,9 @@ function analyseEvent(content: IContent, highlights: Optional<string[]>, opts: E
|
||||
if (opts.forComposerQuote) {
|
||||
sanitizeParams = composerSanitizeHtmlParams;
|
||||
}
|
||||
if (!opts.mediaIsVisible) {
|
||||
sanitizeParams.exclusiveFilter = filterImg;
|
||||
}
|
||||
|
||||
try {
|
||||
const isFormattedBody =
|
||||
|
||||
@@ -7,16 +7,14 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type ReactElement } from "react";
|
||||
import sanitizeHtml, { type IOptions } from "sanitize-html";
|
||||
import sanitizeHtml, { IFrame, type IOptions } from "sanitize-html";
|
||||
import { merge } from "lodash";
|
||||
import _Linkify from "linkify-react";
|
||||
|
||||
import { _linkifyString, ELEMENT_URL_PATTERN, options as linkifyMatrixOptions } from "./linkify-matrix";
|
||||
import SettingsStore from "./settings/SettingsStore";
|
||||
import { tryTransformPermalinkToLocalHref } from "./utils/permalinks/Permalinks";
|
||||
import { mediaFromMxc } from "./customisations/Media";
|
||||
import { PERMITTED_URL_SCHEMES } from "./utils/UrlUtils";
|
||||
import { MediaPreviewValue } from "./@types/media_preview";
|
||||
|
||||
const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
|
||||
const MEDIA_API_MXC_REGEX = /\/_matrix\/media\/r0\/(?:download|thumbnail)\/(.+?)\/(.+?)(?:[?/]|$)/;
|
||||
@@ -48,11 +46,9 @@ export const transformTags: NonNullable<IOptions["transformTags"]> = {
|
||||
// Strip out imgs that aren't `mxc` here instead of using allowedSchemesByTag
|
||||
// because transformTags is used _before_ we filter by allowedSchemesByTag and
|
||||
// we don't want to allow images with `https?` `src`s.
|
||||
// We also drop inline images (as if they were not present at all) when the "show
|
||||
// images" preference is disabled. Future work might expose some UI to reveal them
|
||||
// like standalone image events have.
|
||||
// TODO: Is this a private room?
|
||||
if (!src || SettingsStore.getValue("mediaPreviewConfig").media_previews !== MediaPreviewValue.On) {
|
||||
// Filtering out images now happens as a exlusive filter so we can conditionally apply this
|
||||
// based on settings.
|
||||
if (!src) {
|
||||
return { tagName, attribs: {} };
|
||||
}
|
||||
|
||||
@@ -200,6 +196,7 @@ export const sanitizeHtmlParams: IOptions = {
|
||||
nestingLimit: 50,
|
||||
};
|
||||
|
||||
|
||||
/* Wrapper around linkify-react merging in our default linkify options */
|
||||
export function Linkify({ as, options, children }: React.ComponentProps<typeof _Linkify>): ReactElement {
|
||||
return (
|
||||
@@ -230,3 +227,7 @@ export function linkifyString(str: string, options = linkifyMatrixOptions): stri
|
||||
export function linkifyAndSanitizeHtml(dirtyHtml: string, options = linkifyMatrixOptions): string {
|
||||
return sanitizeHtml(linkifyString(dirtyHtml, options), sanitizeHtmlParams);
|
||||
}
|
||||
|
||||
export function filterImg(frame: IFrame): boolean {
|
||||
return frame.tag === "img";
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext.tsx";
|
||||
import { useSettingValue } from "../../../hooks/useSettings.ts";
|
||||
import { filterBoolean } from "../../../utils/arrays.ts";
|
||||
import { useMediaVisible } from "../../../hooks/useMediaVisible.ts";
|
||||
|
||||
/**
|
||||
* Returns a RegExp pattern for the keyword in the push rule of the given Matrix event, if any
|
||||
@@ -150,6 +151,7 @@ const EventContentBody = memo(
|
||||
forwardRef<HTMLElement, Props>(
|
||||
({ as, mxEvent, stripReply, content, linkify, highlights, includeDir = true, ...options }, ref) => {
|
||||
const enableBigEmoji = useSettingValue("TextualBody.enableBigEmoji");
|
||||
const [mediaIsVisible] = useMediaVisible(mxEvent?.getId()!, mxEvent?.getRoomId()!);
|
||||
|
||||
const replacer = useReplacer(content, mxEvent, options);
|
||||
const linkifyOptions = useMemo(
|
||||
@@ -167,6 +169,7 @@ const EventContentBody = memo(
|
||||
disableBigEmoji: isEmote || !enableBigEmoji,
|
||||
// Part of Replies fallback support
|
||||
stripReplyFallback: stripReply,
|
||||
mediaIsVisible,
|
||||
}),
|
||||
[content, enableBigEmoji, highlights, isEmote, stripReply],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user