diff --git a/ts/components/EditHistoryMessagesModal.dom.tsx b/ts/components/EditHistoryMessagesModal.dom.tsx
index e3696a5b5a..0a307c5f72 100644
--- a/ts/components/EditHistoryMessagesModal.dom.tsx
+++ b/ts/components/EditHistoryMessagesModal.dom.tsx
@@ -62,7 +62,7 @@ const MESSAGE_DEFAULT_PROPS = {
endPoll: shouldNeverBeCalled,
pushPanelForConversation: shouldNeverBeCalled,
renderAudioAttachment: () =>
,
- renderingContext: 'EditHistoryMessagesModal',
+ renderingContext: 'EditHistoryMessagesModal' as const,
saveAttachment: shouldNeverBeCalled,
saveAttachments: shouldNeverBeCalled,
scrollToQuotedMessage: shouldNeverBeCalled,
diff --git a/ts/components/conversation/Message.dom.tsx b/ts/components/conversation/Message.dom.tsx
index 4fa81457e9..4bc82d7fec 100644
--- a/ts/components/conversation/Message.dom.tsx
+++ b/ts/components/conversation/Message.dom.tsx
@@ -46,6 +46,7 @@ import type {
} from './ReactionViewer.dom.js';
import { ReactionViewer } from './ReactionViewer.dom.js';
import { LinkPreviewDate } from './LinkPreviewDate.dom.js';
+import type { RenderingContextType } from '../../types/RenderingContext.d.ts';
import type { LinkPreviewForUIType } from '../../types/message/LinkPreviews.std.js';
import type { MessageStatusType } from '../../types/message/MessageStatus.std.js';
import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage.std.js';
@@ -178,7 +179,7 @@ export enum MessageInteractivity {
}
export type AudioAttachmentProps = {
- renderingContext: string;
+ renderingContext: RenderingContextType;
i18n: LocalizerType;
buttonRef: React.RefObject;
theme: ThemeType | undefined;
@@ -239,7 +240,7 @@ function ReactionEmoji(props: { emojiVariantValue: string }) {
export type PropsData = {
id: string;
- renderingContext: string;
+ renderingContext: RenderingContextType;
contactNameColor?: ContactNameColorType;
conversationColor: ConversationColorType;
conversationTitle: string;
diff --git a/ts/state/ducks/audioPlayer.preload.ts b/ts/state/ducks/audioPlayer.preload.ts
index 324bbc7301..28765086e9 100644
--- a/ts/state/ducks/audioPlayer.preload.ts
+++ b/ts/state/ducks/audioPlayer.preload.ts
@@ -27,6 +27,7 @@ import { isAudio } from '../../util/Attachment.std.js';
import { getLocalAttachmentUrl } from '../../util/getLocalAttachmentUrl.std.js';
import { assertDev } from '../../util/assert.std.js';
import { drop } from '../../util/drop.std.js';
+import type { RenderingContextType } from '../../types/RenderingContext.d.ts';
import { Sound, SoundType } from '../../util/Sound.std.js';
import { DataReader } from '../../sql/Client.preload.js';
@@ -47,7 +48,7 @@ type AudioPlayerContentDraft = ReadonlyDeep<{
/** A voice note consecutive playback */
export type AudioPlayerContentVoiceNote = ReadonlyDeep<{
conversationId: string;
- context: string;
+ context: RenderingContextType;
current: VoiceNoteForPlayback;
// playing because it followed a message
// false on the first of a consecutive group
@@ -214,6 +215,14 @@ function messageAudioEnded(): ThunkAction<
return;
}
+ // No consecutive playback in All Media view
+ if (content.context === 'AllMedia') {
+ dispatch({
+ type: 'audioPlayer/MESSAGE_AUDIO_ENDED',
+ });
+ return;
+ }
+
const { conversationId, context, current } = content;
const next = await getNextVoiceNote({
@@ -314,7 +323,7 @@ function loadVoiceNoteAudio({
}: {
voiceNoteData: VoiceNoteAndConsecutiveForPlayback;
position: number;
- context: string;
+ context: RenderingContextType;
playbackRate: number;
}): SetMessageAudioAction {
const { conversationId, voiceNote } = voiceNoteData;
diff --git a/ts/state/smart/MessageAudio.preload.tsx b/ts/state/smart/MessageAudio.preload.tsx
index d5d3c5faa0..cd02f37a71 100644
--- a/ts/state/smart/MessageAudio.preload.tsx
+++ b/ts/state/smart/MessageAudio.preload.tsx
@@ -3,6 +3,7 @@
import React, { memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
+import type { RenderingContextType } from '../../types/RenderingContext.d.ts';
import { MessageAudio } from '../../components/conversation/MessageAudio.dom.js';
import type { OwnProps as MessageAudioOwnProps } from '../../components/conversation/MessageAudio.dom.js';
import type { ActiveAudioPlayerStateType } from '../ducks/audioPlayer.preload.js';
@@ -24,7 +25,7 @@ import {
const log = createLogger('MessageAudio');
export type Props = Omit & {
- renderingContext: string;
+ renderingContext: RenderingContextType;
};
export const SmartMessageAudio = memo(function SmartMessageAudio({
diff --git a/ts/test-electron/state/selectors/audioPlayer_test.preload.ts b/ts/test-electron/state/selectors/audioPlayer_test.preload.ts
index d507ad9e85..334b4d8362 100644
--- a/ts/test-electron/state/selectors/audioPlayer_test.preload.ts
+++ b/ts/test-electron/state/selectors/audioPlayer_test.preload.ts
@@ -48,7 +48,7 @@ describe('state/selectors/audioPlayer', () => {
actions.loadVoiceNoteAudio({
voiceNoteData: voiceNoteDataForMessage('id'),
position: 0,
- context: 'context',
+ context: 'AllMedia',
playbackRate: 1,
})
);
diff --git a/ts/test-node/state/ducks/audioPlayer_test.preload.ts b/ts/test-node/state/ducks/audioPlayer_test.preload.ts
index 109b80823f..35e06963c8 100644
--- a/ts/test-node/state/ducks/audioPlayer_test.preload.ts
+++ b/ts/test-node/state/ducks/audioPlayer_test.preload.ts
@@ -54,7 +54,7 @@ describe('both/state/ducks/audioPlayer', () => {
actions.loadVoiceNoteAudio({
voiceNoteData: voiceNoteDataForMessage(MESSAGE_ID),
position: 0,
- context: 'context',
+ context: 'AllMedia',
playbackRate: 1,
})
);
@@ -65,7 +65,7 @@ describe('both/state/ducks/audioPlayer', () => {
if (content && AudioPlayerContent.isVoiceNote(content)) {
assert.strictEqual(content.current.id, MESSAGE_ID);
- assert.strictEqual(content.context, 'context');
+ assert.strictEqual(content.context, 'AllMedia');
}
return updated;
@@ -81,7 +81,7 @@ describe('both/state/ducks/audioPlayer', () => {
actions.loadVoiceNoteAudio({
voiceNoteData: voiceNoteDataForMessage('test'),
position: 0,
- context: 'context',
+ context: 'AllMedia',
playbackRate: 1,
})
);
@@ -91,7 +91,7 @@ describe('both/state/ducks/audioPlayer', () => {
if (content && AudioPlayerContent.isVoiceNote(content)) {
assert.strictEqual(content.current.id, 'test');
- assert.strictEqual(content.context, 'context');
+ assert.strictEqual(content.context, 'AllMedia');
}
});
});
diff --git a/ts/types/RenderingContext.d.ts b/ts/types/RenderingContext.d.ts
new file mode 100644
index 0000000000..50df593b92
--- /dev/null
+++ b/ts/types/RenderingContext.d.ts
@@ -0,0 +1,10 @@
+// Copyright 2025 Signal Messenger, LLC
+// SPDX-License-Identifier: AGPL-3.0-only
+
+export type RenderingContextType =
+ | 'EditHistoryMessagesModal'
+ | 'StoryViewsNRepliesModal'
+ | 'conversation/MessageDetail'
+ | 'conversation/TimelineItem'
+ | 'AllMedia'
+ | 'storybook';