Fix error on message details screen with audio messages
This commit is contained in:
parent
5f9a75d9f4
commit
77c306843d
18 changed files with 417 additions and 224 deletions
18
ts/state/roots/createMessageDetail.tsx
Normal file
18
ts/state/roots/createMessageDetail.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { ReactElement } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { Store } from 'redux';
|
||||
|
||||
import { SmartMessageDetail, OwnProps } from '../smart/MessageDetail';
|
||||
|
||||
export const createMessageDetail = (
|
||||
store: Store,
|
||||
props: OwnProps
|
||||
): ReactElement => (
|
||||
<Provider store={store}>
|
||||
<SmartMessageDetail {...props} />
|
||||
</Provider>
|
||||
);
|
111
ts/state/smart/MessageDetail.tsx
Normal file
111
ts/state/smart/MessageDetail.tsx
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ComponentProps } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import {
|
||||
MessageDetail,
|
||||
Contact,
|
||||
} from '../../components/conversation/MessageDetail';
|
||||
import { PropsData as MessagePropsDataType } from '../../components/conversation/Message';
|
||||
import { mapDispatchToProps } from '../actions';
|
||||
|
||||
import { StateType } from '../reducer';
|
||||
import { getIntl, getInteractionMode } from '../selectors/user';
|
||||
import { renderAudioAttachment } from './renderAudioAttachment';
|
||||
import { renderEmojiPicker } from './renderEmojiPicker';
|
||||
|
||||
type MessageDetailProps = ComponentProps<typeof MessageDetail>;
|
||||
|
||||
export type OwnProps = {
|
||||
contacts: Array<Contact>;
|
||||
errors: Array<Error>;
|
||||
message: MessagePropsDataType;
|
||||
receivedAt: number;
|
||||
sentAt: number;
|
||||
} & Pick<
|
||||
MessageDetailProps,
|
||||
| 'clearSelectedMessage'
|
||||
| 'deleteMessage'
|
||||
| 'deleteMessageForEveryone'
|
||||
| 'displayTapToViewMessage'
|
||||
| 'downloadAttachment'
|
||||
| 'kickOffAttachmentDownload'
|
||||
| 'markAttachmentAsCorrupted'
|
||||
| 'openConversation'
|
||||
| 'openLink'
|
||||
| 'reactToMessage'
|
||||
| 'replyToMessage'
|
||||
| 'retrySend'
|
||||
| 'showContactDetail'
|
||||
| 'showContactModal'
|
||||
| 'showExpiredIncomingTapToViewToast'
|
||||
| 'showExpiredOutgoingTapToViewToast'
|
||||
| 'showVisualAttachment'
|
||||
>;
|
||||
|
||||
const mapStateToProps = (
|
||||
state: StateType,
|
||||
props: OwnProps
|
||||
): MessageDetailProps => {
|
||||
const {
|
||||
contacts,
|
||||
errors,
|
||||
message,
|
||||
receivedAt,
|
||||
sentAt,
|
||||
|
||||
clearSelectedMessage,
|
||||
deleteMessage,
|
||||
deleteMessageForEveryone,
|
||||
displayTapToViewMessage,
|
||||
downloadAttachment,
|
||||
kickOffAttachmentDownload,
|
||||
markAttachmentAsCorrupted,
|
||||
openConversation,
|
||||
openLink,
|
||||
reactToMessage,
|
||||
replyToMessage,
|
||||
retrySend,
|
||||
showContactDetail,
|
||||
showContactModal,
|
||||
showExpiredIncomingTapToViewToast,
|
||||
showExpiredOutgoingTapToViewToast,
|
||||
showVisualAttachment,
|
||||
} = props;
|
||||
|
||||
return {
|
||||
contacts,
|
||||
errors,
|
||||
message,
|
||||
receivedAt,
|
||||
sentAt,
|
||||
|
||||
i18n: getIntl(state),
|
||||
interactionMode: getInteractionMode(state),
|
||||
|
||||
clearSelectedMessage,
|
||||
deleteMessage,
|
||||
deleteMessageForEveryone,
|
||||
displayTapToViewMessage,
|
||||
downloadAttachment,
|
||||
kickOffAttachmentDownload,
|
||||
markAttachmentAsCorrupted,
|
||||
openConversation,
|
||||
openLink,
|
||||
reactToMessage,
|
||||
renderAudioAttachment,
|
||||
renderEmojiPicker,
|
||||
replyToMessage,
|
||||
retrySend,
|
||||
showContactDetail,
|
||||
showContactModal,
|
||||
showExpiredIncomingTapToViewToast,
|
||||
showExpiredOutgoingTapToViewToast,
|
||||
showVisualAttachment,
|
||||
};
|
||||
};
|
||||
|
||||
const smart = connect(mapStateToProps, mapDispatchToProps);
|
||||
export const SmartMessageDetail = smart(MessageDetail);
|
|
@ -1,13 +1,11 @@
|
|||
// Copyright 2019-2020 Signal Messenger, LLC
|
||||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { pick } from 'lodash';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { mapDispatchToProps } from '../actions';
|
||||
import { GlobalAudioContext } from '../../components/GlobalAudioContext';
|
||||
import { Timeline } from '../../components/conversation/Timeline';
|
||||
import { RenderEmojiPickerProps } from '../../components/conversation/ReactionPicker';
|
||||
import { StateType } from '../reducer';
|
||||
|
||||
import { getIntl } from '../selectors/user';
|
||||
|
@ -23,8 +21,8 @@ import { SmartTypingBubble } from './TypingBubble';
|
|||
import { SmartLastSeenIndicator } from './LastSeenIndicator';
|
||||
import { SmartHeroRow } from './HeroRow';
|
||||
import { SmartTimelineLoadingRow } from './TimelineLoadingRow';
|
||||
import { SmartEmojiPicker } from './EmojiPicker';
|
||||
import { SmartMessageAudio, Props as MessageAudioProps } from './MessageAudio';
|
||||
import { renderAudioAttachment } from './renderAudioAttachment';
|
||||
import { renderEmojiPicker } from './renderEmojiPicker';
|
||||
|
||||
// Workaround: A react component's required properties are filtering up through connect()
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31363
|
||||
|
@ -43,11 +41,6 @@ type ExternalProps = {
|
|||
// are provided by ConversationView in setupTimeline().
|
||||
};
|
||||
|
||||
type AudioAttachmentProps = Omit<
|
||||
MessageAudioProps,
|
||||
'audio' | 'audioContext' | 'waveformCache'
|
||||
>;
|
||||
|
||||
function renderItem(
|
||||
messageId: string,
|
||||
conversationId: string,
|
||||
|
@ -64,35 +57,6 @@ function renderItem(
|
|||
);
|
||||
}
|
||||
|
||||
function renderAudioAttachment(props: AudioAttachmentProps) {
|
||||
return (
|
||||
<GlobalAudioContext.Consumer>
|
||||
{globalAudioProps => {
|
||||
return (
|
||||
globalAudioProps && (
|
||||
<SmartMessageAudio {...props} {...globalAudioProps} />
|
||||
)
|
||||
);
|
||||
}}
|
||||
</GlobalAudioContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
function renderEmojiPicker({
|
||||
ref,
|
||||
onPickEmoji,
|
||||
onClose,
|
||||
style,
|
||||
}: RenderEmojiPickerProps): JSX.Element {
|
||||
return (
|
||||
<SmartEmojiPicker
|
||||
ref={ref}
|
||||
onPickEmoji={onPickEmoji}
|
||||
onClose={onClose}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
function renderLastSeenIndicator(id: string): JSX.Element {
|
||||
return <FilteredSmartLastSeenIndicator id={id} />;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2019-2020 Signal Messenger, LLC
|
||||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
|
@ -8,7 +8,7 @@ import { mapDispatchToProps } from '../actions';
|
|||
import { StateType } from '../reducer';
|
||||
|
||||
import { TimelineItem } from '../../components/conversation/TimelineItem';
|
||||
import { getIntl, getTheme } from '../selectors/user';
|
||||
import { getIntl, getInteractionMode, getTheme } from '../selectors/user';
|
||||
import {
|
||||
getMessageSelector,
|
||||
getSelectedMessage,
|
||||
|
@ -47,6 +47,7 @@ const mapStateToProps = (state: StateType, props: ExternalProps) => {
|
|||
isSelected,
|
||||
renderContact,
|
||||
i18n: getIntl(state),
|
||||
interactionMode: getInteractionMode(state),
|
||||
theme: getTheme(state),
|
||||
};
|
||||
};
|
||||
|
|
27
ts/state/smart/renderAudioAttachment.tsx
Normal file
27
ts/state/smart/renderAudioAttachment.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { ReactElement } from 'react';
|
||||
import { GlobalAudioContext } from '../../components/GlobalAudioContext';
|
||||
import { SmartMessageAudio, Props as MessageAudioProps } from './MessageAudio';
|
||||
|
||||
type AudioAttachmentProps = Omit<
|
||||
MessageAudioProps,
|
||||
'audio' | 'audioContext' | 'waveformCache'
|
||||
>;
|
||||
|
||||
export function renderAudioAttachment(
|
||||
props: AudioAttachmentProps
|
||||
): ReactElement {
|
||||
return (
|
||||
<GlobalAudioContext.Consumer>
|
||||
{globalAudioProps => {
|
||||
return (
|
||||
globalAudioProps && (
|
||||
<SmartMessageAudio {...props} {...globalAudioProps} />
|
||||
)
|
||||
);
|
||||
}}
|
||||
</GlobalAudioContext.Consumer>
|
||||
);
|
||||
}
|
23
ts/state/smart/renderEmojiPicker.tsx
Normal file
23
ts/state/smart/renderEmojiPicker.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { RenderEmojiPickerProps } from '../../components/conversation/ReactionPicker';
|
||||
import { SmartEmojiPicker } from './EmojiPicker';
|
||||
|
||||
export function renderEmojiPicker({
|
||||
ref,
|
||||
onPickEmoji,
|
||||
onClose,
|
||||
style,
|
||||
}: RenderEmojiPickerProps): JSX.Element {
|
||||
return (
|
||||
<SmartEmojiPicker
|
||||
ref={ref}
|
||||
onPickEmoji={onPickEmoji}
|
||||
onClose={onClose}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue