From 6fa005dcfc0033587a2a31025823794c34b32896 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Tue, 6 Jun 2023 09:20:21 +0100
Subject: [PATCH] Inhibit interactions on forward dialog message previews
 (#11025)

* Inhibit interactions on forward dialog message previews

and improve inhibiting of video message body

* Consolidate prop types

* Iterate

* Update src/components/views/messages/IBodyProps.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
---
 .../views/dialogs/ForwardDialog.tsx           |  8 +++-
 src/components/views/messages/IBodyProps.ts   |  4 ++
 src/components/views/messages/MVideoBody.tsx  |  4 +-
 .../views/messages/MessageEvent.tsx           |  1 +
 src/events/EventTileFactory.tsx               | 37 +++++++++++--------
 5 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/src/components/views/dialogs/ForwardDialog.tsx b/src/components/views/dialogs/ForwardDialog.tsx
index 75af82d86a..d1be021988 100644
--- a/src/components/views/dialogs/ForwardDialog.tsx
+++ b/src/components/views/dialogs/ForwardDialog.tsx
@@ -284,7 +284,13 @@ const ForwardDialog: React.FC<IProps> = ({ matrixClient: cli, event, permalinkCr
                     mx_IRCLayout: previewLayout == Layout.IRC,
                 })}
             >
-                <EventTile mxEvent={mockEvent} layout={previewLayout} permalinkCreator={permalinkCreator} as="div" />
+                <EventTile
+                    mxEvent={mockEvent}
+                    layout={previewLayout}
+                    permalinkCreator={permalinkCreator}
+                    as="div"
+                    inhibitInteraction
+                />
             </div>
             <hr />
             <div className="mx_ForwardList" id="mx_ForwardList">
diff --git a/src/components/views/messages/IBodyProps.ts b/src/components/views/messages/IBodyProps.ts
index e9b853621a..17981be54c 100644
--- a/src/components/views/messages/IBodyProps.ts
+++ b/src/components/views/messages/IBodyProps.ts
@@ -55,4 +55,8 @@ export interface IBodyProps {
     getRelationsForEvent?: GetRelationsForEvent;
 
     ref?: React.RefObject<any> | LegacyRef<any>;
+
+    // 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;
 }
diff --git a/src/components/views/messages/MVideoBody.tsx b/src/components/views/messages/MVideoBody.tsx
index 5ecf74a8b6..5fdbc42d36 100644
--- a/src/components/views/messages/MVideoBody.tsx
+++ b/src/components/views/messages/MVideoBody.tsx
@@ -234,7 +234,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
 
     public render(): React.ReactNode {
         const content = this.props.mxEvent.getContent();
-        const autoplay = SettingsStore.getValue("autoplayVideo");
+        const autoplay = !this.props.inhibitInteraction && SettingsStore.getValue("autoplayVideo");
 
         let aspectRatio;
         if (content.info?.w && content.info?.h) {
@@ -287,7 +287,7 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
                         ref={this.videoRef}
                         src={contentUrl}
                         title={content.body}
-                        controls
+                        controls={!this.props.inhibitInteraction}
                         // Disable downloading as it doesn't work with e2ee video,
                         // users should use the dedicated Download button in the Message Action Bar
                         controlsList="nodownload"
diff --git a/src/components/views/messages/MessageEvent.tsx b/src/components/views/messages/MessageEvent.tsx
index 4fd84e31f1..3eb1cfbb60 100644
--- a/src/components/views/messages/MessageEvent.tsx
+++ b/src/components/views/messages/MessageEvent.tsx
@@ -213,6 +213,7 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
                 mediaEventHelper={this.mediaHelper}
                 getRelationsForEvent={this.props.getRelationsForEvent}
                 isSeeingThroughMessageHiddenForModeration={this.props.isSeeingThroughMessageHiddenForModeration}
+                inhibitInteraction={this.props.inhibitInteraction}
             />
         ) : null;
     }
diff --git a/src/events/EventTileFactory.tsx b/src/events/EventTileFactory.tsx
index 4b7fc1cbba..ae3f66ba74 100644
--- a/src/events/EventTileFactory.tsx
+++ b/src/events/EventTileFactory.tsx
@@ -23,10 +23,8 @@ import { MatrixClient } from "matrix-js-sdk/src/client";
 import { GroupCallIntent } from "matrix-js-sdk/src/webrtc/groupCall";
 
 import SettingsStore from "../settings/SettingsStore";
-import EditorStateTransfer from "../utils/EditorStateTransfer";
-import { RoomPermalinkCreator } from "../utils/permalinks/Permalinks";
 import LegacyCallEventGrouper from "../components/structures/LegacyCallEventGrouper";
-import { GetRelationsForEvent } from "../components/views/rooms/EventTile";
+import { EventTileProps } from "../components/views/rooms/EventTile";
 import { TimelineRenderingType } from "../contexts/RoomContext";
 import MessageEvent from "../components/views/messages/MessageEvent";
 import MKeyVerificationConclusion from "../components/views/messages/MKeyVerificationConclusion";
@@ -56,20 +54,24 @@ import {
 } from "../voice-broadcast";
 
 // Subset of EventTile's IProps plus some mixins
-export interface EventTileTypeProps {
+export interface EventTileTypeProps
+    extends Pick<
+        EventTileProps,
+        | "mxEvent"
+        | "highlights"
+        | "highlightLink"
+        | "showUrlPreview"
+        | "onHeightChanged"
+        | "forExport"
+        | "getRelationsForEvent"
+        | "editState"
+        | "replacingEventId"
+        | "permalinkCreator"
+        | "callEventGrouper"
+        | "isSeeingThroughMessageHiddenForModeration"
+        | "inhibitInteraction"
+    > {
     ref?: React.RefObject<any>; // `any` because it's effectively impossible to convince TS of a reasonable type
-    mxEvent: MatrixEvent;
-    highlights?: string[];
-    highlightLink?: string;
-    showUrlPreview?: boolean;
-    onHeightChanged?: () => void;
-    forExport?: boolean;
-    getRelationsForEvent?: GetRelationsForEvent;
-    editState?: EditorStateTransfer;
-    replacingEventId?: string;
-    permalinkCreator?: RoomPermalinkCreator;
-    callEventGrouper?: LegacyCallEventGrouper;
-    isSeeingThroughMessageHiddenForModeration?: boolean;
     timestamp?: JSX.Element;
     maxImageHeight?: number; // pixels
     overrideBodyTypes?: Record<string, typeof React.Component>;
@@ -322,6 +324,7 @@ export function renderTile(
         getRelationsForEvent,
         isSeeingThroughMessageHiddenForModeration,
         timestamp,
+        inhibitInteraction,
     } = props;
 
     switch (renderType) {
@@ -340,6 +343,7 @@ export function renderTile(
                 getRelationsForEvent,
                 isSeeingThroughMessageHiddenForModeration,
                 permalinkCreator,
+                inhibitInteraction,
             });
         default:
             // NEARLY ALL THE OPTIONS!
@@ -357,6 +361,7 @@ export function renderTile(
                 getRelationsForEvent,
                 isSeeingThroughMessageHiddenForModeration,
                 timestamp,
+                inhibitInteraction,
             });
     }
 }