diff --git a/lib/hooks/message-hooks.js b/lib/hooks/message-hooks.js
--- a/lib/hooks/message-hooks.js
+++ b/lib/hooks/message-hooks.js
@@ -2,8 +2,10 @@
 
 import * as React from 'react';
 
+import { useGetLatestMessageEdit } from './latest-message-edit.js';
 import { messageInfoSelector } from '../selectors/chat-selectors.js';
 import { getOldestNonLocalMessageID } from '../shared/message-utils.js';
+import { messageSpecs } from '../shared/messages/message-specs.js';
 import type { MessageInfo } from '../types/message-types.js';
 import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import { useSelector } from '../utils/redux-utils.js';
@@ -19,21 +21,42 @@
 ) => Promise<?MessageInfo> {
   const messageInfos = useSelector(messageInfoSelector);
   const messageStore = useSelector(state => state.messageStore);
+  const viewerID = useSelector(state => state.currentUserInfo?.id);
+  const fetchMessage = useGetLatestMessageEdit();
   return React.useCallback(
     async threadInfo => {
+      if (!viewerID) {
+        return null;
+      }
       const thread = messageStore.threads[threadInfo.id];
       if (!thread) {
         return null;
       }
+      const showInMessagePreviewParams = {
+        threadInfo,
+        viewerID,
+        fetchMessage,
+      };
       for (const messageID of thread.messageIDs) {
         const messageInfo = messageInfos[messageID];
-        if (messageInfo) {
+        if (!messageInfo) {
+          continue;
+        }
+        const { showInMessagePreview } = messageSpecs[messageInfo.type];
+        if (!showInMessagePreview) {
+          return messageInfo;
+        }
+        const shouldShow = await showInMessagePreview(
+          messageInfo,
+          showInMessagePreviewParams,
+        );
+        if (shouldShow) {
           return messageInfo;
         }
       }
       return null;
     },
-    [messageInfos, messageStore],
+    [messageInfos, messageStore, viewerID, fetchMessage],
   );
 }
 
diff --git a/lib/shared/messages/message-spec.js b/lib/shared/messages/message-spec.js
--- a/lib/shared/messages/message-spec.js
+++ b/lib/shared/messages/message-spec.js
@@ -76,6 +76,12 @@
   | { +shouldMerge: false }
   | { +shouldMerge: true, +item: RobotextChatMessageInfoItem };
 
+export type ShowInMessagePreviewParams = {
+  +threadInfo: ThreadInfo,
+  +viewerID: string,
+  +fetchMessage: (messageID: string) => Promise<?RawMessageInfo>,
+};
+
 export type MessageSpec<Data, RawInfo, Info> = {
   +messageContentForServerDB?: (data: Data | RawInfo) => string,
   +messageContentForClientDB?: (data: RawInfo) => string,
@@ -131,4 +137,8 @@
     precedingMessageInfoItem: RobotextChatMessageInfoItem,
     params: RobotextParams,
   ) => MergeRobotextMessageItemResult,
+  +showInMessagePreview?: (
+    messageInfo: Info,
+    params: ShowInMessagePreviewParams,
+  ) => Promise<boolean>,
 };
diff --git a/lib/shared/messages/multimedia-message-spec.js b/lib/shared/messages/multimedia-message-spec.js
--- a/lib/shared/messages/multimedia-message-spec.js
+++ b/lib/shared/messages/multimedia-message-spec.js
@@ -369,6 +369,9 @@
   canBePinned: true,
 
   validator: rawMultimediaMessageInfoValidator,
+
+  showInMessagePreview: (messageInfo: MediaMessageInfo | ImagesMessageInfo) =>
+    Promise.resolve(messageInfo.media.length > 0),
 });
 
 // Four photos were uploaded before dimensions were calculated server-side,