diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss
index ea81ab11a73..dc7f0379a96 100644
--- a/stylesheets/_modules.scss
+++ b/stylesheets/_modules.scss
@@ -10059,9 +10059,20 @@ $contact-modal-padding: 18px;
   padding: 3px;
 }
 .module-delivery-issue-dialog__button {
+}
+
+.module-delivery-issue-dialog__learn-more-button {
+  @include button-reset;
+  @include button-secondary;
   @include font-body-1-bold;
+
+  border-radius: 4px;
+  padding: 7px 14px;
+}
+.module-delivery-issue-dialog__close-button {
   @include button-reset;
   @include button-primary;
+  @include font-body-1-bold;
 
   border-radius: 4px;
   padding: 7px 14px;
diff --git a/ts/components/AvatarPopup.tsx b/ts/components/AvatarPopup.tsx
index 3b91f522613..f1295703f3e 100644
--- a/ts/components/AvatarPopup.tsx
+++ b/ts/components/AvatarPopup.tsx
@@ -23,7 +23,6 @@ export type Props = {
 } & AvatarProps;
 
 export const AvatarPopup = (props: Props): JSX.Element => {
-  const focusRef = React.useRef<HTMLButtonElement>(null);
   const {
     i18n,
     name,
@@ -42,7 +41,7 @@ export const AvatarPopup = (props: Props): JSX.Element => {
   // Note: mechanisms to dismiss this view are all in its host, MainHeader
 
   // Focus first button after initial render, restore focus on teardown
-  useRestoreFocus(focusRef);
+  const [focusRef] = useRestoreFocus();
 
   return (
     <div style={style} className="module-avatar-popup">
diff --git a/ts/components/CaptchaDialog.tsx b/ts/components/CaptchaDialog.tsx
index dbfdbd93eaf..86bb9c53790 100644
--- a/ts/components/CaptchaDialog.tsx
+++ b/ts/components/CaptchaDialog.tsx
@@ -39,6 +39,7 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
         moduleClassName="module-Modal"
         i18n={i18n}
         title={i18n('CaptchaDialog--can-close__title')}
+        onClose={() => setIsClosing(false)}
       >
         <section>
           <p>{i18n('CaptchaDialog--can-close__body')}</p>
diff --git a/ts/components/NeedsScreenRecordingPermissionsModal.tsx b/ts/components/NeedsScreenRecordingPermissionsModal.tsx
index a3c1c1da4c5..bcbf0b92b7c 100644
--- a/ts/components/NeedsScreenRecordingPermissionsModal.tsx
+++ b/ts/components/NeedsScreenRecordingPermissionsModal.tsx
@@ -29,6 +29,7 @@ export const NeedsScreenRecordingPermissionsModal = ({
       i18n={i18n}
       title={i18n('calling__presenting--permission-title')}
       theme={Theme.Dark}
+      onClose={toggleScreenRecordingPermissionsDialog}
     >
       <p>{i18n('calling__presenting--macos-permission-description')}</p>
       <ol style={{ paddingLeft: 16 }}>
diff --git a/ts/components/SafetyNumberChangeDialog.tsx b/ts/components/SafetyNumberChangeDialog.tsx
index 70fec246c12..cea73dbb19a 100644
--- a/ts/components/SafetyNumberChangeDialog.tsx
+++ b/ts/components/SafetyNumberChangeDialog.tsx
@@ -54,7 +54,7 @@ export const SafetyNumberChangeDialog = ({
 
   if (selectedContact) {
     return (
-      <Modal i18n={i18n}>
+      <Modal i18n={i18n} onClose={onClose}>
         {renderSafetyNumber({ contactID: selectedContact.id, onClose })}
       </Modal>
     );
diff --git a/ts/components/ShortcutGuide.tsx b/ts/components/ShortcutGuide.tsx
index 4adf76dbff1..fd1fce9e6c3 100644
--- a/ts/components/ShortcutGuide.tsx
+++ b/ts/components/ShortcutGuide.tsx
@@ -205,12 +205,11 @@ const CALLING_SHORTCUTS: Array<ShortcutType> = [
 ];
 
 export const ShortcutGuide = (props: Props): JSX.Element => {
-  const focusRef = React.useRef<HTMLDivElement>(null);
   const { i18n, close, hasInstalledStickers, platform } = props;
   const isMacOS = platform === 'darwin';
 
   // Restore focus on teardown
-  useRestoreFocus(focusRef);
+  const [focusRef] = useRestoreFocus();
 
   return (
     <div className="module-shortcut-guide">
diff --git a/ts/components/conversation/ChatSessionRefreshedDialog.tsx b/ts/components/conversation/ChatSessionRefreshedDialog.tsx
index 0bcda908fd8..6487639ec01 100644
--- a/ts/components/conversation/ChatSessionRefreshedDialog.tsx
+++ b/ts/components/conversation/ChatSessionRefreshedDialog.tsx
@@ -6,6 +6,8 @@ import classNames from 'classnames';
 
 import { Modal } from '../Modal';
 
+import { useRestoreFocus } from '../../util/hooks';
+
 import { LocalizerType } from '../../types/Util';
 
 export type PropsType = {
@@ -19,8 +21,11 @@ export function ChatSessionRefreshedDialog(
 ): React.ReactElement {
   const { i18n, contactSupport, onClose } = props;
 
+  // Focus first button after initial render, restore focus on teardown
+  const [focusRef] = useRestoreFocus();
+
   return (
-    <Modal hasXButton={false} i18n={i18n}>
+    <Modal hasXButton={false} onClose={onClose} i18n={i18n}>
       <div className="module-chat-session-refreshed-dialog">
         <div className="module-chat-session-refreshed-dialog__image">
           <img
@@ -50,6 +55,7 @@ export function ChatSessionRefreshedDialog(
           <button
             type="button"
             onClick={onClose}
+            ref={focusRef}
             className="module-chat-session-refreshed-dialog__button"
           >
             {i18n('Confirmation--confirm')}
diff --git a/ts/components/conversation/DeliveryIssueDialog.stories.tsx b/ts/components/conversation/DeliveryIssueDialog.stories.tsx
index 7ddc1f9cd65..6c68051b931 100644
--- a/ts/components/conversation/DeliveryIssueDialog.stories.tsx
+++ b/ts/components/conversation/DeliveryIssueDialog.stories.tsx
@@ -21,6 +21,7 @@ storiesOf('Components/Conversation/DeliveryIssueDialog', module).add(
         i18n={i18n}
         sender={sender}
         inGroup={false}
+        learnMoreAboutDeliveryIssue={action('learnMoreAboutDeliveryIssue')}
         onClose={action('onClose')}
       />
     );
@@ -35,6 +36,7 @@ storiesOf('Components/Conversation/DeliveryIssueDialog', module).add(
         i18n={i18n}
         sender={sender}
         inGroup
+        learnMoreAboutDeliveryIssue={action('learnMoreAboutDeliveryIssue')}
         onClose={action('onClose')}
       />
     );
diff --git a/ts/components/conversation/DeliveryIssueDialog.tsx b/ts/components/conversation/DeliveryIssueDialog.tsx
index bae85be7f34..b7da93fd45e 100644
--- a/ts/components/conversation/DeliveryIssueDialog.tsx
+++ b/ts/components/conversation/DeliveryIssueDialog.tsx
@@ -8,24 +8,30 @@ import { Modal } from '../Modal';
 import { Intl } from '../Intl';
 import { Emojify } from './Emojify';
 
+import { useRestoreFocus } from '../../util/hooks';
+
 import { LocalizerType } from '../../types/Util';
 
 export type PropsType = {
   i18n: LocalizerType;
   sender: ConversationType;
   inGroup: boolean;
+  learnMoreAboutDeliveryIssue: () => unknown;
   onClose: () => unknown;
 };
 
 export function DeliveryIssueDialog(props: PropsType): React.ReactElement {
-  const { i18n, inGroup, sender, onClose } = props;
+  const { i18n, inGroup, learnMoreAboutDeliveryIssue, sender, onClose } = props;
 
   const key = inGroup
     ? 'DeliveryIssue--summary--group'
     : 'DeliveryIssue--summary';
 
+  // Focus first button after initial render, restore focus on teardown
+  const [focusRef] = useRestoreFocus();
+
   return (
-    <Modal hasXButton={false} i18n={i18n}>
+    <Modal hasXButton={false} onClose={onClose} i18n={i18n}>
       <div className="module-delivery-issue-dialog">
         <div className="module-delivery-issue-dialog__image">
           <img
@@ -48,10 +54,18 @@ export function DeliveryIssueDialog(props: PropsType): React.ReactElement {
           />
         </div>
         <div className="module-delivery-issue-dialog__buttons">
+          <button
+            type="button"
+            onClick={learnMoreAboutDeliveryIssue}
+            className="module-delivery-issue-dialog__learn-more-button"
+          >
+            {i18n('DeliveryIssue--learnMore')}
+          </button>
           <button
             type="button"
             onClick={onClose}
-            className="module-delivery-issue-dialog__button"
+            ref={focusRef}
+            className="module-delivery-issue-dialog__close-button"
           >
             {i18n('Confirmation--confirm')}
           </button>
diff --git a/ts/components/conversation/DeliveryIssueNotification.stories.tsx b/ts/components/conversation/DeliveryIssueNotification.stories.tsx
index 38659d6dc06..824a13bb9d2 100644
--- a/ts/components/conversation/DeliveryIssueNotification.stories.tsx
+++ b/ts/components/conversation/DeliveryIssueNotification.stories.tsx
@@ -6,6 +6,7 @@
 
 import * as React from 'react';
 import { storiesOf } from '@storybook/react';
+import { action } from '@storybook/addon-actions';
 
 import { setup as setupI18n } from '../../../js/modules/i18n';
 import enMessages from '../../../_locales/en/messages.json';
@@ -19,7 +20,12 @@ storiesOf('Components/Conversation/DeliveryIssueNotification', module).add(
   'Default',
   () => {
     return (
-      <DeliveryIssueNotification i18n={i18n} inGroup={false} sender={sender} />
+      <DeliveryIssueNotification
+        i18n={i18n}
+        inGroup={false}
+        learnMoreAboutDeliveryIssue={action('learnMoreAboutDeliveryIssue')}
+        sender={sender}
+      />
     );
   }
 );
@@ -27,6 +33,13 @@ storiesOf('Components/Conversation/DeliveryIssueNotification', module).add(
 storiesOf('Components/Conversation/DeliveryIssueNotification', module).add(
   'In Group',
   () => {
-    return <DeliveryIssueNotification i18n={i18n} inGroup sender={sender} />;
+    return (
+      <DeliveryIssueNotification
+        i18n={i18n}
+        inGroup
+        learnMoreAboutDeliveryIssue={action('learnMoreAboutDeliveryIssue')}
+        sender={sender}
+      />
+    );
   }
 );
diff --git a/ts/components/conversation/DeliveryIssueNotification.tsx b/ts/components/conversation/DeliveryIssueNotification.tsx
index 0519803c601..2235a4bb4c8 100644
--- a/ts/components/conversation/DeliveryIssueNotification.tsx
+++ b/ts/components/conversation/DeliveryIssueNotification.tsx
@@ -15,16 +15,22 @@ export type PropsDataType = {
   inGroup: boolean;
 };
 
+export type PropsActionsType = {
+  learnMoreAboutDeliveryIssue: () => unknown;
+};
+
 type PropsHousekeepingType = {
   i18n: LocalizerType;
 };
 
-export type PropsType = PropsDataType & PropsHousekeepingType;
+export type PropsType = PropsDataType &
+  PropsActionsType &
+  PropsHousekeepingType;
 
 export function DeliveryIssueNotification(
   props: PropsType
 ): ReactElement | null {
-  const { i18n, inGroup, sender } = props;
+  const { i18n, inGroup, sender, learnMoreAboutDeliveryIssue } = props;
   const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
 
   const openDialog = useCallback(() => {
@@ -61,6 +67,7 @@ export function DeliveryIssueNotification(
         <DeliveryIssueDialog
           i18n={i18n}
           inGroup={inGroup}
+          learnMoreAboutDeliveryIssue={learnMoreAboutDeliveryIssue}
           sender={sender}
           onClose={closeDialog}
         />
diff --git a/ts/components/conversation/ReactionPicker.tsx b/ts/components/conversation/ReactionPicker.tsx
index ac9111c87a4..8042c61874e 100644
--- a/ts/components/conversation/ReactionPicker.tsx
+++ b/ts/components/conversation/ReactionPicker.tsx
@@ -40,7 +40,6 @@ export const ReactionPicker = React.forwardRef<HTMLDivElement, Props>(
     ref
   ) => {
     const [pickingOther, setPickingOther] = React.useState(false);
-    const focusRef = React.useRef<HTMLButtonElement>(null);
 
     // Handle escape key
     React.useEffect(() => {
@@ -70,7 +69,7 @@ export const ReactionPicker = React.forwardRef<HTMLDivElement, Props>(
     );
 
     // Focus first button and restore focus on unmount
-    useRestoreFocus(focusRef);
+    const [focusRef] = useRestoreFocus();
 
     const otherSelected = selected && !emojis.includes(selected);
 
diff --git a/ts/components/conversation/ReactionViewer.tsx b/ts/components/conversation/ReactionViewer.tsx
index 4133b152e9b..2f9d81df2e0 100644
--- a/ts/components/conversation/ReactionViewer.tsx
+++ b/ts/components/conversation/ReactionViewer.tsx
@@ -124,8 +124,6 @@ export const ReactionViewer = React.forwardRef<HTMLDivElement, Props>(
       selectedReactionCategory,
       setSelectedReactionCategory,
     ] = React.useState(pickedReaction || 'all');
-    const focusRef = React.useRef<HTMLButtonElement>(null);
-
     // Handle escape key
     React.useEffect(() => {
       const handler = (e: KeyboardEvent) => {
@@ -142,7 +140,7 @@ export const ReactionViewer = React.forwardRef<HTMLDivElement, Props>(
     }, [onClose]);
 
     // Focus first button and restore focus on unmount
-    useRestoreFocus(focusRef);
+    const [focusRef] = useRestoreFocus();
 
     // If we have previously selected a reaction type that is no longer present
     // (removed on another device, for instance) we should select another
diff --git a/ts/components/conversation/Timeline.stories.tsx b/ts/components/conversation/Timeline.stories.tsx
index d51e4a84468..b0cce695e21 100644
--- a/ts/components/conversation/Timeline.stories.tsx
+++ b/ts/components/conversation/Timeline.stories.tsx
@@ -304,6 +304,7 @@ const actions = () => ({
   ),
   setLoadCountdownStart: action('setLoadCountdownStart'),
   setIsNearBottom: action('setIsNearBottom'),
+  learnMoreAboutDeliveryIssue: action('learnMoreAboutDeliveryIssue'),
   loadAndScroll: action('loadAndScroll'),
   loadOlderMessages: action('loadOlderMessages'),
   loadNewerMessages: action('loadNewerMessages'),
diff --git a/ts/components/conversation/Timeline.tsx b/ts/components/conversation/Timeline.tsx
index 9ff5acdc0a8..8485b3fac19 100644
--- a/ts/components/conversation/Timeline.tsx
+++ b/ts/components/conversation/Timeline.tsx
@@ -135,6 +135,7 @@ type PropsActionsType = {
     }>
   ) => void;
 
+  learnMoreAboutDeliveryIssue: () => unknown;
   loadAndScroll: (messageId: string) => unknown;
   loadOlderMessages: (messageId: string) => unknown;
   loadNewerMessages: (messageId: string) => unknown;
diff --git a/ts/components/conversation/TimelineItem.stories.tsx b/ts/components/conversation/TimelineItem.stories.tsx
index 18d3c81c10b..2b6acb29f63 100644
--- a/ts/components/conversation/TimelineItem.stories.tsx
+++ b/ts/components/conversation/TimelineItem.stories.tsx
@@ -55,6 +55,7 @@ const getDefaultProps = () => ({
   deleteMessage: action('deleteMessage'),
   deleteMessageForEveryone: action('deleteMessageForEveryone'),
   kickOffAttachmentDownload: action('kickOffAttachmentDownload'),
+  learnMoreAboutDeliveryIssue: action('learnMoreAboutDeliveryIssue'),
   markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'),
   showMessageDetail: action('showMessageDetail'),
   openConversation: action('openConversation'),
diff --git a/ts/components/conversation/TimelineItem.tsx b/ts/components/conversation/TimelineItem.tsx
index 3d95b9ed738..9ebb8f5e1ab 100644
--- a/ts/components/conversation/TimelineItem.tsx
+++ b/ts/components/conversation/TimelineItem.tsx
@@ -21,6 +21,7 @@ import {
 } from './ChatSessionRefreshedNotification';
 import {
   DeliveryIssueNotification,
+  PropsActionsType as DeliveryIssueActionProps,
   PropsDataType as DeliveryIssueProps,
 } from './DeliveryIssueNotification';
 import { CallingNotificationType } from '../../util/callingNotification';
@@ -156,6 +157,7 @@ type PropsLocalType = {
 
 type PropsActionsType = MessageActionsType &
   CallingNotificationActionsType &
+  DeliveryIssueActionProps &
   PropsChatSessionRefreshedActionsType &
   UnsupportedMessageActionsType &
   SafetyNumberActionsType;
@@ -226,7 +228,9 @@ export class TimelineItem extends React.PureComponent<PropsType> {
         />
       );
     } else if (item.type === 'deliveryIssue') {
-      notification = <DeliveryIssueNotification {...item.data} i18n={i18n} />;
+      notification = (
+        <DeliveryIssueNotification {...item.data} {...this.props} i18n={i18n} />
+      );
     } else if (item.type === 'linkNotification') {
       notification = (
         <div className="module-message-unsynced">
diff --git a/ts/components/stickers/StickerPicker.tsx b/ts/components/stickers/StickerPicker.tsx
index 0055c5a68bd..e6b21a2308d 100644
--- a/ts/components/stickers/StickerPicker.tsx
+++ b/ts/components/stickers/StickerPicker.tsx
@@ -70,7 +70,6 @@ export const StickerPicker = React.memo(
       }: Props,
       ref
     ) => {
-      const focusRef = React.useRef<HTMLButtonElement>(null);
       const tabIds = React.useMemo(
         () => ['recents', ...packs.map(({ id }) => id)],
         [packs]
@@ -124,7 +123,7 @@ export const StickerPicker = React.memo(
       }, [onClose]);
 
       // Focus popup on after initial render, restore focus on teardown
-      useRestoreFocus(focusRef);
+      const [focusRef] = useRestoreFocus();
 
       const isEmpty = stickers.length === 0;
       const addPackRef = isEmpty ? focusRef : undefined;
diff --git a/ts/components/stickers/StickerPreviewModal.tsx b/ts/components/stickers/StickerPreviewModal.tsx
index 138a4b34481..1808f7ca493 100644
--- a/ts/components/stickers/StickerPreviewModal.tsx
+++ b/ts/components/stickers/StickerPreviewModal.tsx
@@ -76,12 +76,11 @@ export const StickerPreviewModal = React.memo((props: Props) => {
     installStickerPack,
     uninstallStickerPack,
   } = props;
-  const focusRef = React.useRef<HTMLButtonElement>(null);
   const [root, setRoot] = React.useState<HTMLElement | null>(null);
   const [confirmingUninstall, setConfirmingUninstall] = React.useState(false);
 
   // Restore focus on teardown
-  useRestoreFocus(focusRef, root);
+  const [focusRef] = useRestoreFocus();
 
   React.useEffect(() => {
     const div = document.createElement('div');
diff --git a/ts/util/hooks.ts b/ts/util/hooks.ts
index a6f3f534a96..8567a96dca9 100644
--- a/ts/util/hooks.ts
+++ b/ts/util/hooks.ts
@@ -13,34 +13,47 @@ export function usePrevious<T>(initialValue: T, currentValue: T): T {
   return result;
 }
 
+type CallbackType = (toFocus: HTMLElement | null | undefined) => void;
+
 // Restore focus on teardown
-export const useRestoreFocus = (
-  // The ref for the element to receive initial focus
-  focusRef: React.RefObject<HTMLElement>,
-  // Allow for an optional root element that must exist
-  root: boolean | HTMLElement | null = true
-): void => {
+export const useRestoreFocus = (): Array<CallbackType> => {
+  const toFocusRef = React.useRef<HTMLElement | null>(null);
+  const lastFocusedRef = React.useRef<HTMLElement | null>(null);
+
+  // We need to use a callback here because refs aren't necessarily populated on first
+  //   render. For example, ModalHost makes a top-level parent div first, and then renders
+  //   into it. And the children you pass it don't have access to that root div.
+  const setFocusRef = React.useCallback(
+    (toFocus: HTMLElement | null | undefined) => {
+      if (!toFocus) {
+        return;
+      }
+
+      // We only want to do this once.
+      if (toFocusRef.current) {
+        return;
+      }
+      toFocusRef.current = toFocus;
+
+      // Remember last-focused element, focus this new target element.
+      lastFocusedRef.current = document.activeElement as HTMLElement;
+      toFocus.focus();
+    },
+    []
+  );
+
   React.useEffect(() => {
-    if (!root) {
-      return undefined;
-    }
-
-    const lastFocused = document.activeElement as HTMLElement;
-
-    if (focusRef.current) {
-      focusRef.current.focus();
-    }
-
     return () => {
-      // This ensures that the focus is returned to
-      // previous element
+      // On unmount, returned focus to element focused before we set the focus
       setTimeout(() => {
-        if (lastFocused && lastFocused.focus) {
-          lastFocused.focus();
+        if (lastFocusedRef.current && lastFocusedRef.current.focus) {
+          lastFocusedRef.current.focus();
         }
       });
     };
-  }, [focusRef, root]);
+  }, []);
+
+  return [setFocusRef];
 };
 
 export const useBoundActions = <T extends ActionCreatorsMapObject>(
diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json
index 7aaf7e876da..15c9da006ce 100644
--- a/ts/util/lint/exceptions.json
+++ b/ts/util/lint/exceptions.json
@@ -13058,6 +13058,13 @@
     "reasonCategory": "falseMatch",
     "updated": "2018-09-19T21:59:32.770Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "sticker-creator/components/StickerFrame.tsx",
+    "line": "    const timerRef = React.useRef<number>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "jQuery-$(",
     "path": "sticker-creator/util/i18n.tsx",
@@ -13184,6 +13191,13 @@
     "updated": "2021-01-06T00:47:54.313Z",
     "reasonDetail": "Needed to render remote video elements. Doesn't interact with the DOM."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/calling/useGetCallingFrameBuffer.ts",
+    "line": "  const ref = useRef<ArrayBuffer | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "jQuery-load(",
     "path": "ts/challenge.js",
@@ -13235,6 +13249,20 @@
     "updated": "2021-03-01T18:34:36.638Z",
     "reasonDetail": "Used to reference popup menu"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/AvatarInput.tsx",
+    "line": "  const fileInputRef = useRef<null | HTMLInputElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/AvatarInput.tsx",
+    "line": "  const menuTriggerRef = useRef<null | any>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/AvatarInputContainer.js",
@@ -13244,11 +13272,10 @@
   },
   {
     "rule": "React-useRef",
-    "path": "ts/components/AvatarPopup.js",
-    "line": "    const focusRef = React.useRef(null);",
+    "path": "ts/components/AvatarInputContainer.tsx",
+    "line": "  const startingAvatarPathRef = useRef<undefined | string>(avatarPath);",
     "reasonCategory": "usageTrusted",
-    "updated": "2020-10-26T19:12:24.410Z",
-    "reasonDetail": "Only used to focus the element."
+    "updated": "2021-07-30T16:57:33.618Z"
   },
   {
     "rule": "React-useRef",
@@ -13264,6 +13291,20 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-06-09T04:02:08.305Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/BackboneHost.tsx",
+    "line": "  const hostRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/BackboneHost.tsx",
+    "line": "  const viewRef = useRef<Backbone.View | undefined>(undefined);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CallNeedPermissionScreen.js",
@@ -13272,6 +13313,13 @@
     "updated": "2020-10-26T19:12:24.410Z",
     "reasonDetail": "Doesn't touch the DOM."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CallNeedPermissionScreen.tsx",
+    "line": "  const autoCloseAtRef = useRef<number>(Date.now() + AUTO_CLOSE_MS);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CallScreen.js",
@@ -13280,6 +13328,13 @@
     "updated": "2020-10-26T21:35:52.858Z",
     "reasonDetail": "Used to get the local video element for rendering."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CallScreen.tsx",
+    "line": "  const localVideoRef = useRef<HTMLVideoElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CallingLobby.js",
@@ -13288,6 +13343,13 @@
     "updated": "2020-10-26T19:12:24.410Z",
     "reasonDetail": "Used to get the local video element for rendering."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CallingLobby.tsx",
+    "line": "  const localVideoRef = React.useRef<null | HTMLVideoElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CallingPip.js",
@@ -13312,6 +13374,13 @@
     "updated": "2020-10-26T19:12:24.410Z",
     "reasonDetail": "Used to get the local video element for rendering."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CallingPip.tsx",
+    "line": "  const videoContainerRef = React.useRef<null | HTMLDivElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CallingToastManager.js",
@@ -13319,6 +13388,13 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-05-13T19:40:31.751Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CallingToastManager.tsx",
+    "line": "  const timeoutRef = useRef<NodeJS.Timeout | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CaptchaDialog.js",
@@ -13327,6 +13403,13 @@
     "updated": "2021-05-05T23:11:22.692Z",
     "reasonDetail": "Used only to set focus"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CaptchaDialog.tsx",
+    "line": "  const buttonRef = useRef<HTMLButtonElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-createRef",
     "path": "ts/components/CaptionEditor.js",
@@ -13350,6 +13433,13 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-05-25T18:25:53.896Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/ChatColorPicker.tsx",
+    "line": "  const menuRef = useRef<any | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "DOM-innerHTML",
     "path": "ts/components/CompositionArea.js",
@@ -13382,6 +13472,20 @@
     "updated": "2020-06-03T19:23:21.195Z",
     "reasonDetail": "Our code, no user input, only clearing out the dom"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionArea.tsx",
+    "line": "  const inputApiRef = React.useRef<InputApi | undefined>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionArea.tsx",
+    "line": "  const micCellRef = React.useRef<HTMLDivElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/CompositionInput.js",
@@ -13444,6 +13548,48 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-04-21T21:35:38.757Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionInput.tsx",
+    "line": "  const emojiCompletionRef = React.useRef<EmojiCompletion>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionInput.tsx",
+    "line": "  const mentionCompletionRef = React.useRef<MentionCompletion>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionInput.tsx",
+    "line": "  const quillRef = React.useRef<Quill>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionInput.tsx",
+    "line": "  const scrollerRef = React.useRef<HTMLDivElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionInput.tsx",
+    "line": "  const propsRef = React.useRef<Props>(props);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/CompositionInput.tsx",
+    "line": "  const memberRepositoryRef = React.useRef<MemberRepository>(",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/ContactPills.js",
@@ -13452,6 +13598,13 @@
     "updated": "2021-03-01T18:34:36.638Z",
     "reasonDetail": "Used for scrolling. Doesn't otherwise manipulate the DOM"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/ContactPills.tsx",
+    "line": "  const elRef = useRef<null | HTMLDivElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/ConversationList.js",
@@ -13460,6 +13613,13 @@
     "updated": "2021-02-12T16:25:08.285Z",
     "reasonDetail": "Used for scroll calculations"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/ConversationList.tsx",
+    "line": "  const listRef = useRef<null | List>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/DirectCallRemoteParticipant.js",
@@ -13468,6 +13628,13 @@
     "updated": "2020-11-11T21:56:04.179Z",
     "reasonDetail": "Needed to render the remote video element."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/DirectCallRemoteParticipant.tsx",
+    "line": "  const remoteVideoRef = useRef<HTMLCanvasElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/ForwardMessageModal.js",
@@ -13482,6 +13649,20 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-04-19T18:13:21.664Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/ForwardMessageModal.tsx",
+    "line": "  const inputRef = useRef<null | HTMLInputElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/ForwardMessageModal.tsx",
+    "line": "  const inputApiRef = React.useRef<InputApi | undefined>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/GradientDial.js",
@@ -13489,6 +13670,13 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-05-25T18:25:53.896Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/GradientDial.tsx",
+    "line": "  const containerRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/GroupCallOverflowArea.js",
@@ -13497,6 +13685,13 @@
     "updated": "2021-01-08T15:48:46.313Z",
     "reasonDetail": "Used to deal with scroll position."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/GroupCallOverflowArea.tsx",
+    "line": "  const overflowRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/GroupCallRemoteParticipant.js",
@@ -13529,6 +13724,20 @@
     "updated": "2021-06-17T20:46:02.342Z",
     "reasonDetail": "Doesn't reference the DOM."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/GroupCallRemoteParticipant.tsx",
+    "line": "    const remoteVideoRef = useRef<HTMLCanvasElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/GroupCallRemoteParticipant.tsx",
+    "line": "    const canvasContextRef = useRef<CanvasRenderingContext2D | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/Inbox.js",
@@ -13543,6 +13752,20 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-06-08T02:49:25.154Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Inbox.tsx",
+    "line": "  const hostRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Inbox.tsx",
+    "line": "  const viewRef = useRef<InboxViewType | undefined>(undefined);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/Input.js",
@@ -13564,6 +13787,27 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-07-14T00:50:58.330Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Input.tsx",
+    "line": "    const innerRef = useRef<HTMLInputElement | HTMLTextAreaElement | null>(",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Input.tsx",
+    "line": "    const valueOnKeydownRef = useRef<string>(value);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Input.tsx",
+    "line": "    const selectionStartOnKeydownRef = useRef<number>(value.length);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "jQuery-$(",
     "path": "ts/components/Intl.js",
@@ -13624,6 +13868,13 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-07-14T00:50:58.330Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/ProfileEditor.tsx",
+    "line": "  const focusInputRef = useRef<HTMLInputElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-createRef",
     "path": "ts/components/SafetyNumberChangeDialog.js",
@@ -13632,14 +13883,6 @@
     "updated": "2020-06-23T06:48:06.829Z",
     "reasonDetail": "Used to focus cancel button when dialog opens"
   },
-  {
-    "rule": "React-useRef",
-    "path": "ts/components/ShortcutGuide.js",
-    "line": "    const focusRef = React.useRef(null);",
-    "reasonCategory": "usageTrusted",
-    "updated": "2020-10-26T19:12:24.410Z",
-    "reasonDetail": "Only used to focus the element."
-  },
   {
     "rule": "React-useRef",
     "path": "ts/components/Slider.js",
@@ -13661,6 +13904,27 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-05-25T18:25:53.896Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Slider.tsx",
+    "line": "  const diff = useRef<number>(0);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Slider.tsx",
+    "line": "  const handleRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Slider.tsx",
+    "line": "  const sliderRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/Tooltip.js",
@@ -13669,6 +13933,13 @@
     "updated": "2020-12-04T00:11:08.128Z",
     "reasonDetail": "Used to add (and remove) event listeners."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/Tooltip.tsx",
+    "line": "  const wrapperRef = React.useRef<HTMLSpanElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/conversation/ContactModal.js",
@@ -13683,6 +13954,20 @@
     "reasonCategory": "usageTrusted",
     "updated": "2020-11-10T21:27:04.909Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/ContactModal.tsx",
+    "line": "  const overlayRef = React.useRef<HTMLElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/ContactModal.tsx",
+    "line": "  const closeButtonRef = React.useRef<HTMLElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-createRef",
     "path": "ts/components/conversation/ConversationHeader.js",
@@ -13723,6 +14008,13 @@
     "updated": "2020-10-26T19:12:24.410Z",
     "reasonDetail": "Doesn't refer to a DOM element."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/ConversationHero.tsx",
+    "line": "  const previousHeightRef = useRef<undefined | number>();",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/conversation/GIF.js",
@@ -13731,6 +14023,13 @@
     "updated": "2021-04-17T01:47:31.419Z",
     "reasonDetail": "Used for managing playback of GIF video"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/GIF.tsx",
+    "line": "  const videoRef = useRef<HTMLVideoElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/conversation/GroupDescription.js",
@@ -13738,6 +14037,13 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-05-29T02:15:39.186Z"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/GroupDescription.tsx",
+    "line": "  const textRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-createRef",
     "path": "ts/components/conversation/InlineNotificationWrapper.js",
@@ -13810,6 +14116,13 @@
     "updated": "2021-03-09T01:19:04.057Z",
     "reasonDetail": "Used for obtanining the bounding box for the container"
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/MessageAudio.tsx",
+    "line": "  const waveformRef = useRef<HTMLDivElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-createRef",
     "path": "ts/components/conversation/MessageDetail.js",
@@ -13834,22 +14147,6 @@
     "updated": "2021-01-20T21:30:08.430Z",
     "reasonDetail": "Doesn't touch the DOM."
   },
-  {
-    "rule": "React-useRef",
-    "path": "ts/components/conversation/ReactionPicker.js",
-    "line": "    const focusRef = React.useRef(null);",
-    "reasonCategory": "usageTrusted",
-    "updated": "2020-10-26T19:12:24.410Z",
-    "reasonDetail": "Only used to focus the element."
-  },
-  {
-    "rule": "React-useRef",
-    "path": "ts/components/conversation/ReactionViewer.js",
-    "line": "    const focusRef = React.useRef(null);",
-    "reasonCategory": "usageTrusted",
-    "updated": "2020-10-26T19:12:24.410Z",
-    "reasonDetail": "Only used to focus the element."
-  },
   {
     "rule": "React-createRef",
     "path": "ts/components/conversation/Timeline.js",
@@ -13866,6 +14163,13 @@
     "updated": "2021-03-11T20:49:17.292Z",
     "reasonDetail": "Used to focus an input."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.tsx",
+    "line": "  const inputRef = useRef<null | HTMLInputElement>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-useRef",
     "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.js",
@@ -13890,6 +14194,27 @@
     "updated": "2021-06-04T14:19:49.714Z",
     "reasonDetail": "Only stores undefined/true/false, not DOM references."
   },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.tsx",
+    "line": "  const focusDescriptionRef = useRef<undefined | boolean>(",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.tsx",
+    "line": "  const startingTitleRef = useRef<string>(externalTitle);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.tsx",
+    "line": "  const startingAvatarPathRef = useRef<undefined | string>(externalAvatarPath);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
   {
     "rule": "React-createRef",
     "path": "ts/components/conversation/media-gallery/MediaGallery.js",
@@ -13914,22 +14239,6 @@
     "updated": "2019-11-21T06:13:49.384Z",
     "reasonDetail": "Used for setting focus only"
   },
-  {
-    "rule": "React-useRef",
-    "path": "ts/components/stickers/StickerPicker.js",
-    "line": "    const focusRef = React.useRef(null);",
-    "reasonCategory": "usageTrusted",
-    "updated": "2020-10-26T19:12:24.410Z",
-    "reasonDetail": "Only used to focus the element."
-  },
-  {
-    "rule": "React-useRef",
-    "path": "ts/components/stickers/StickerPreviewModal.js",
-    "line": "    const focusRef = React.useRef(null);",
-    "reasonCategory": "usageTrusted",
-    "updated": "2020-10-26T19:12:24.410Z",
-    "reasonDetail": "Only used to focus the element."
-  },
   {
     "rule": "jQuery-append(",
     "path": "ts/logging/debuglogs.js",
@@ -14102,5 +14411,49 @@
     "reasonCategory": "usageTrusted",
     "updated": "2021-03-18T21:41:28.361Z",
     "reasonDetail": "A generic hook. Typically not to be used with non-DOM values."
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/util/hooks.js",
+    "line": "    const toFocusRef = React.useRef(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T01:08:01.309Z",
+    "reasonDetail": "Used to set focus"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/util/hooks.js",
+    "line": "    const lastFocusedRef = React.useRef(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T01:08:01.309Z",
+    "reasonDetail": "Used to store the previous-focused item, again to set focus"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/util/hooks.ts",
+    "line": "  const previousValueRef = React.useRef<T>(initialValue);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/util/hooks.ts",
+    "line": "  const toFocusRef = React.useRef<HTMLElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/util/hooks.ts",
+    "line": "  const lastFocusedRef = React.useRef<HTMLElement | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
+  },
+  {
+    "rule": "React-useRef",
+    "path": "ts/util/hooks.ts",
+    "line": "  const unobserveRef = React.useRef<(() => unknown) | null>(null);",
+    "reasonCategory": "usageTrusted",
+    "updated": "2021-07-30T16:57:33.618Z"
   }
 ]
\ No newline at end of file
diff --git a/ts/util/lint/rules.json b/ts/util/lint/rules.json
index e183ba86f8c..ed83b7161d6 100644
--- a/ts/util/lint/rules.json
+++ b/ts/util/lint/rules.json
@@ -137,7 +137,7 @@
   },
   {
     "name": "React-useRef",
-    "expression": "\\buseRef\\(",
+    "expression": "\\buseRef(\\(|<)",
     "reason": "Potential XSS",
     "excludedModules": ["node_modules/react/", "node_modules/react-dom"]
   },
diff --git a/ts/views/conversation_view.ts b/ts/views/conversation_view.ts
index c5e914ed21b..984636f075c 100644
--- a/ts/views/conversation_view.ts
+++ b/ts/views/conversation_view.ts
@@ -903,6 +903,10 @@ Whisper.ConversationView = Whisper.View.extend({
       this.navigateTo(url);
     };
 
+    const learnMoreAboutDeliveryIssue = () => {
+      this.navigateTo('https://support.signal.org/hc/articles/4404859745690');
+    };
+
     const scrollToQuotedMessage = async (options: any) => {
       const { authorId, sentAt } = options;
 
@@ -1079,6 +1083,7 @@ Whisper.ConversationView = Whisper.View.extend({
           model.acknowledgeGroupMemberNameCollisions(groupNameCollisions);
         },
         contactSupport,
+        learnMoreAboutDeliveryIssue,
         loadNewerMessages,
         loadNewestMessages: this.loadNewestMessages.bind(this),
         loadAndScroll: this.loadAndScroll.bind(this),