Standardize on showConversation function, delete unused functions
This commit is contained in:
parent
1dc3ed914f
commit
f2f1c3c021
35 changed files with 174 additions and 198 deletions
|
@ -158,6 +158,8 @@ import type AccountManager from './textsecure/AccountManager';
|
|||
import { onStoryRecipientUpdate } from './util/onStoryRecipientUpdate';
|
||||
import { StoryViewModeType, StoryViewTargetType } from './types/Stories';
|
||||
import { downloadOnboardingStory } from './util/downloadOnboardingStory';
|
||||
import { clearConversationDraftAttachments } from './util/clearConversationDraftAttachments';
|
||||
import { removeLinkPreview } from './services/LinkPreview';
|
||||
|
||||
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
|
||||
|
||||
|
@ -1545,10 +1547,9 @@ export async function startApp(): Promise<void> {
|
|||
showToast(ToastConversationArchived, {
|
||||
undo: () => {
|
||||
conversation.setArchived(false);
|
||||
window.Whisper.events.trigger(
|
||||
'showConversation',
|
||||
conversation.get('id')
|
||||
);
|
||||
window.reduxActions.conversations.showConversation({
|
||||
conversationId: conversation.get('id'),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1702,7 +1703,7 @@ export async function startApp(): Promise<void> {
|
|||
!shiftKey &&
|
||||
(key === 'p' || key === 'P')
|
||||
) {
|
||||
conversation.trigger('remove-link-review');
|
||||
removeLinkPreview();
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
@ -1716,7 +1717,10 @@ export async function startApp(): Promise<void> {
|
|||
shiftKey &&
|
||||
(key === 'p' || key === 'P')
|
||||
) {
|
||||
conversation.trigger('remove-all-draft-attachments');
|
||||
clearConversationDraftAttachments(
|
||||
conversation.id,
|
||||
conversation.get('draftAttachments')
|
||||
);
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
@ -1924,7 +1928,10 @@ export async function startApp(): Promise<void> {
|
|||
viewTarget: StoryViewTargetType.Replies,
|
||||
});
|
||||
} else {
|
||||
window.Whisper.events.trigger('showConversation', id, messageId);
|
||||
window.reduxActions.conversations.showConversation({
|
||||
conversationId: id,
|
||||
messageId,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
window.reduxActions.app.openInbox();
|
||||
|
|
|
@ -167,20 +167,20 @@ export function AddUserToAnotherGroupModal({
|
|||
>
|
||||
<ConversationList
|
||||
dimensions={contentRect.bounds}
|
||||
rowCount={filteredConversations.length}
|
||||
getRow={handleGetRow}
|
||||
shouldRecomputeRowHeights={false}
|
||||
showConversation={noop}
|
||||
getPreferredBadge={() => undefined}
|
||||
getRow={handleGetRow}
|
||||
i18n={i18n}
|
||||
theme={theme}
|
||||
lookupConversationWithoutUuid={async _ => undefined}
|
||||
onClickArchiveButton={noop}
|
||||
onClickContactCheckbox={noop}
|
||||
onSelectConversation={setSelectedGroupId}
|
||||
showChooseGroupMembers={noop}
|
||||
lookupConversationWithoutUuid={async _ => undefined}
|
||||
showUserNotFoundModal={noop}
|
||||
rowCount={filteredConversations.length}
|
||||
setIsFetchingUUID={noop}
|
||||
shouldRecomputeRowHeights={false}
|
||||
showChooseGroupMembers={noop}
|
||||
showConversation={noop}
|
||||
showUserNotFoundModal={noop}
|
||||
theme={theme}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
import type {
|
||||
ConversationType,
|
||||
ShowConversationType,
|
||||
} from '../state/ducks/conversations';
|
||||
import { Intl } from './Intl';
|
||||
import type { LocalizerType, ThemeType } from '../types/Util';
|
||||
import { Modal } from './Modal';
|
||||
|
@ -11,14 +14,14 @@ import { ConversationListItem } from './conversationList/ConversationListItem';
|
|||
type PropsType = {
|
||||
groupAdmins: Array<ConversationType>;
|
||||
i18n: LocalizerType;
|
||||
openConversation: (conversationId: string) => unknown;
|
||||
showConversation: ShowConversationType;
|
||||
theme: ThemeType;
|
||||
};
|
||||
|
||||
export function AnnouncementsOnlyGroupBanner({
|
||||
groupAdmins,
|
||||
i18n,
|
||||
openConversation,
|
||||
showConversation,
|
||||
theme,
|
||||
}: PropsType): JSX.Element {
|
||||
const [isShowingAdmins, setIsShowingAdmins] = useState(false);
|
||||
|
@ -35,13 +38,13 @@ export function AnnouncementsOnlyGroupBanner({
|
|||
{groupAdmins.map(admin => (
|
||||
<ConversationListItem
|
||||
{...admin}
|
||||
i18n={i18n}
|
||||
onClick={() => {
|
||||
openConversation(admin.id);
|
||||
}}
|
||||
draftPreview=""
|
||||
i18n={i18n}
|
||||
lastMessage={undefined}
|
||||
lastUpdated={undefined}
|
||||
onClick={() => {
|
||||
showConversation({ conversationId: admin.id });
|
||||
}}
|
||||
theme={theme}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -117,8 +117,8 @@ const useProps = (overrideProps: Partial<Props> = {}): Props => ({
|
|||
),
|
||||
areWeAdmin: boolean('areWeAdmin', Boolean(overrideProps.areWeAdmin)),
|
||||
groupAdmins: [],
|
||||
openConversation: action('openConversation'),
|
||||
onCancelJoinRequest: action('onCancelJoinRequest'),
|
||||
showConversation: action('showConversation'),
|
||||
// SMS-only
|
||||
isSMSOnly: overrideProps.isSMSOnly || false,
|
||||
isFetchingUUID: overrideProps.isFetchingUUID || false,
|
||||
|
|
|
@ -40,7 +40,10 @@ import type {
|
|||
import { isImageAttachment } from '../types/Attachment';
|
||||
import { AudioCapture } from './conversation/AudioCapture';
|
||||
import { CompositionUpload } from './CompositionUpload';
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
import type {
|
||||
ConversationType,
|
||||
ShowConversationType,
|
||||
} from '../state/ducks/conversations';
|
||||
import type { EmojiPickDataType } from './emoji/EmojiPicker';
|
||||
import type { LinkPreviewType } from '../types/message/LinkPreviews';
|
||||
|
||||
|
@ -117,7 +120,6 @@ export type OwnProps = Readonly<{
|
|||
voiceNoteAttachment?: InMemoryAttachmentDraftType;
|
||||
}
|
||||
): unknown;
|
||||
openConversation(conversationId: string): unknown;
|
||||
quotedMessageId?: string;
|
||||
quotedMessageProps?: Omit<
|
||||
QuoteProps,
|
||||
|
@ -131,6 +133,7 @@ export type OwnProps = Readonly<{
|
|||
messageId: string | undefined
|
||||
): unknown;
|
||||
shouldSendHighQualityAttachments: boolean;
|
||||
showConversation: ShowConversationType;
|
||||
startRecording: () => unknown;
|
||||
theme: ThemeType;
|
||||
}>;
|
||||
|
@ -257,7 +260,7 @@ export function CompositionArea({
|
|||
areWeAdmin,
|
||||
groupAdmins,
|
||||
onCancelJoinRequest,
|
||||
openConversation,
|
||||
showConversation,
|
||||
// SMS-only contacts
|
||||
isSMSOnly,
|
||||
isFetchingUUID,
|
||||
|
@ -594,7 +597,7 @@ export function CompositionArea({
|
|||
<AnnouncementsOnlyGroupBanner
|
||||
groupAdmins={groupAdmins}
|
||||
i18n={i18n}
|
||||
openConversation={openConversation}
|
||||
showConversation={showConversation}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -135,10 +135,6 @@ export function Inbox({
|
|||
prevConversation.trigger('unload', 'force unload requested');
|
||||
}
|
||||
|
||||
function onShowConversation(id: string, messageId?: string): void {
|
||||
showConversation({ conversationId: id, messageId });
|
||||
}
|
||||
|
||||
function packInstallFailed() {
|
||||
showToast(ToastStickerPackInstallFailed);
|
||||
}
|
||||
|
@ -147,14 +143,12 @@ export function Inbox({
|
|||
window.Whisper.events.on('pack-install-failed', packInstallFailed);
|
||||
window.Whisper.events.on('refreshConversation', refreshConversation);
|
||||
window.Whisper.events.on('setupAsNewDevice', unload);
|
||||
window.Whisper.events.on('showConversation', onShowConversation);
|
||||
|
||||
return () => {
|
||||
window.Whisper.events.off('loadingProgress', setLoadingMessageCount);
|
||||
window.Whisper.events.off('pack-install-failed', packInstallFailed);
|
||||
window.Whisper.events.off('refreshConversation', refreshConversation);
|
||||
window.Whisper.events.off('setupAsNewDevice', unload);
|
||||
window.Whisper.events.off('showConversation', onShowConversation);
|
||||
};
|
||||
}, [prevConversation, showConversation]);
|
||||
|
||||
|
|
|
@ -148,8 +148,8 @@ const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
|
|||
getPreferredBadge={() => undefined}
|
||||
i18n={i18n}
|
||||
id={id}
|
||||
showConversation={action('showConversation')}
|
||||
sentAt={1587358800000}
|
||||
showConversation={action('showConversation')}
|
||||
snippet="Lorem <<left>>ipsum<<right>> wow"
|
||||
theme={ThemeType.light}
|
||||
to={defaultConversations[1]}
|
||||
|
|
|
@ -142,7 +142,6 @@ export type PropsType = {
|
|||
|
||||
export function LeftPane({
|
||||
challengeStatus,
|
||||
crashReportCount,
|
||||
clearConversationSearch,
|
||||
clearGroupCreationError,
|
||||
clearSearch,
|
||||
|
@ -151,9 +150,11 @@ export function LeftPane({
|
|||
composeDeleteAvatarFromDisk,
|
||||
composeReplaceAvatar,
|
||||
composeSaveAvatarToDisk,
|
||||
crashReportCount,
|
||||
createGroup,
|
||||
getPreferredBadge,
|
||||
i18n,
|
||||
lookupConversationWithoutUuid,
|
||||
modeSpecificProps,
|
||||
preferredWidthFromStorage,
|
||||
renderCaptchaDialog,
|
||||
|
@ -173,19 +174,18 @@ export function LeftPane({
|
|||
setComposeGroupExpireTimer,
|
||||
setComposeGroupName,
|
||||
setComposeSearchTerm,
|
||||
setIsFetchingUUID,
|
||||
showArchivedConversations,
|
||||
showChooseGroupMembers,
|
||||
showConversation,
|
||||
showInbox,
|
||||
showUserNotFoundModal,
|
||||
startComposing,
|
||||
startSearch,
|
||||
showUserNotFoundModal,
|
||||
setIsFetchingUUID,
|
||||
lookupConversationWithoutUuid,
|
||||
toggleConversationInChooseMembers,
|
||||
showConversation,
|
||||
startSettingGroupMetadata,
|
||||
theme,
|
||||
toggleComposeEditingAvatar,
|
||||
toggleConversationInChooseMembers,
|
||||
updateSearchTerm,
|
||||
}: PropsType): JSX.Element {
|
||||
const [preferredWidth, setPreferredWidth] = useState(
|
||||
|
|
|
@ -16,15 +16,15 @@ type PropsType = {
|
|||
clearSearch: () => void;
|
||||
disabled?: boolean;
|
||||
i18n: LocalizerType;
|
||||
searchConversation?: ConversationType;
|
||||
searchTerm: string;
|
||||
startSearchCounter: number;
|
||||
updateSearchTerm: (searchTerm: string) => void;
|
||||
showConversation: ShowConversationType;
|
||||
onEnterKeyDown?: (
|
||||
clearSearch: () => void,
|
||||
showConversation: ShowConversationType
|
||||
) => void;
|
||||
searchConversation?: ConversationType;
|
||||
searchTerm: string;
|
||||
showConversation: ShowConversationType;
|
||||
startSearchCounter: number;
|
||||
updateSearchTerm: (searchTerm: string) => void;
|
||||
};
|
||||
|
||||
export function LeftPaneSearchInput({
|
||||
|
@ -32,12 +32,12 @@ export function LeftPaneSearchInput({
|
|||
clearSearch,
|
||||
disabled,
|
||||
i18n,
|
||||
onEnterKeyDown,
|
||||
searchConversation,
|
||||
searchTerm,
|
||||
showConversation,
|
||||
startSearchCounter,
|
||||
updateSearchTerm,
|
||||
showConversation,
|
||||
onEnterKeyDown,
|
||||
}: PropsType): JSX.Element {
|
||||
const inputRef = useRef<null | HTMLInputElement>(null);
|
||||
|
||||
|
|
|
@ -1193,22 +1193,22 @@ export function EditDistributionListModal({
|
|||
getPreferredBadge={getPreferredBadge}
|
||||
getRow={getRow}
|
||||
i18n={i18n}
|
||||
lookupConversationWithoutUuid={asyncShouldNeverBeCalled}
|
||||
onClickArchiveButton={shouldNeverBeCalled}
|
||||
onClickContactCheckbox={(conversationId: string) => {
|
||||
toggleSelectedConversation(conversationId);
|
||||
}}
|
||||
lookupConversationWithoutUuid={asyncShouldNeverBeCalled}
|
||||
showConversation={shouldNeverBeCalled}
|
||||
showUserNotFoundModal={shouldNeverBeCalled}
|
||||
setIsFetchingUUID={shouldNeverBeCalled}
|
||||
onSelectConversation={shouldNeverBeCalled}
|
||||
renderMessageSearchResult={() => {
|
||||
shouldNeverBeCalled();
|
||||
return <div />;
|
||||
}}
|
||||
rowCount={rowCount}
|
||||
setIsFetchingUUID={shouldNeverBeCalled}
|
||||
shouldRecomputeRowHeights={false}
|
||||
showChooseGroupMembers={shouldNeverBeCalled}
|
||||
showConversation={shouldNeverBeCalled}
|
||||
showUserNotFoundModal={shouldNeverBeCalled}
|
||||
theme={ThemeType.dark}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -57,7 +57,7 @@ const MESSAGE_DEFAULT_PROPS = {
|
|||
markViewed: shouldNeverBeCalled,
|
||||
messageExpanded: shouldNeverBeCalled,
|
||||
// Called when clicking mention, but shouldn't do anything.
|
||||
openConversation: noop,
|
||||
showConversation: noop,
|
||||
openGiftBadge: shouldNeverBeCalled,
|
||||
openLink: shouldNeverBeCalled,
|
||||
previews: [],
|
||||
|
|
|
@ -20,7 +20,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
|||
{ incoming: 'incoming', outgoing: 'outgoing' },
|
||||
overrideProps.direction || 'incoming'
|
||||
),
|
||||
openConversation: action('openConversation'),
|
||||
showConversation: action('showConversation'),
|
||||
text: text('text', overrideProps.text || ''),
|
||||
});
|
||||
|
||||
|
|
|
@ -13,14 +13,17 @@ import type {
|
|||
export type Props = {
|
||||
bodyRanges?: HydratedBodyRangesType;
|
||||
direction?: 'incoming' | 'outgoing';
|
||||
openConversation?: (conversationId: string, messageId?: string) => void;
|
||||
showConversation?: (options: {
|
||||
conversationId: string;
|
||||
messageId?: string;
|
||||
}) => unknown;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export function AtMentionify({
|
||||
bodyRanges,
|
||||
direction,
|
||||
openConversation,
|
||||
showConversation,
|
||||
text,
|
||||
}: Props): JSX.Element {
|
||||
if (!bodyRanges) {
|
||||
|
@ -53,17 +56,17 @@ export function AtMentionify({
|
|||
className={`MessageBody__at-mention MessageBody__at-mention--${direction}`}
|
||||
key={range.start}
|
||||
onClick={() => {
|
||||
if (openConversation) {
|
||||
openConversation(range.conversationID);
|
||||
if (showConversation) {
|
||||
showConversation({ conversationId: range.conversationID });
|
||||
}
|
||||
}}
|
||||
onKeyUp={e => {
|
||||
if (
|
||||
e.target === e.currentTarget &&
|
||||
e.keyCode === 13 &&
|
||||
openConversation
|
||||
showConversation
|
||||
) {
|
||||
openConversation(range.conversationID);
|
||||
showConversation({ conversationId: range.conversationID });
|
||||
}
|
||||
}}
|
||||
tabIndex={0}
|
||||
|
|
|
@ -63,8 +63,8 @@ enum SubModalState {
|
|||
}
|
||||
|
||||
export function ContactModal({
|
||||
areWeASubscriber,
|
||||
areWeAdmin,
|
||||
areWeASubscriber,
|
||||
badges,
|
||||
contact,
|
||||
conversation,
|
||||
|
@ -76,9 +76,9 @@ export function ContactModal({
|
|||
removeMemberFromGroup,
|
||||
showConversation,
|
||||
theme,
|
||||
toggleAddUserToAnotherGroupModal,
|
||||
toggleAdmin,
|
||||
toggleSafetyNumberModal,
|
||||
toggleAddUserToAnotherGroupModal,
|
||||
updateConversationModelSharedGroups,
|
||||
viewUserStories,
|
||||
}: PropsType): JSX.Element {
|
||||
|
|
|
@ -81,23 +81,21 @@ export type PropsDataType = {
|
|||
|
||||
export type PropsActionsType = {
|
||||
destroyMessages: (conversationId: string) => void;
|
||||
onSearchInConversation: () => void;
|
||||
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
||||
onOutgoingVideoCallInConversation: (conversationId: string) => void;
|
||||
|
||||
onShowConversationDetails: () => void;
|
||||
onShowAllMedia: () => void;
|
||||
onShowGroupMembers: () => void;
|
||||
onGoBack: () => void;
|
||||
|
||||
onArchive: () => void;
|
||||
onGoBack: () => void;
|
||||
onMarkUnread: () => void;
|
||||
onMoveToInbox: () => void;
|
||||
setMuteExpiration: (conversationId: string, seconds: number) => void;
|
||||
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
||||
onOutgoingVideoCallInConversation: (conversationId: string) => void;
|
||||
onSearchInConversation: () => void;
|
||||
onShowAllMedia: () => void;
|
||||
onShowConversationDetails: () => void;
|
||||
onShowGroupMembers: () => void;
|
||||
setDisappearingMessages: (
|
||||
conversationId: string,
|
||||
seconds: DurationInSeconds
|
||||
) => void;
|
||||
setMuteExpiration: (conversationId: string, seconds: number) => void;
|
||||
setPinned: (conversationId: string, value: boolean) => void;
|
||||
viewUserStories: ViewUserStoriesActionCreatorType;
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@ import type {
|
|||
ConversationTypeType,
|
||||
InteractionModeType,
|
||||
SaveAttachmentActionCreatorType,
|
||||
ShowConversationType,
|
||||
} from '../../state/ducks/conversations';
|
||||
import type { ViewStoryActionCreatorType } from '../../state/ducks/stories';
|
||||
import type { ReadStatus } from '../../messages/MessageReadStatus';
|
||||
|
@ -299,7 +300,7 @@ export type PropsActions = {
|
|||
showMessageDetail: (id: string) => void;
|
||||
|
||||
startConversation: (e164: string, uuid: UUIDStringType) => void;
|
||||
openConversation: (conversationId: string, messageId?: string) => void;
|
||||
showConversation: ShowConversationType;
|
||||
openGiftBadge: (messageId: string) => void;
|
||||
showContactDetail: (options: {
|
||||
contact: EmbeddedContactType;
|
||||
|
@ -1709,13 +1710,13 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
displayLimit,
|
||||
i18n,
|
||||
id,
|
||||
messageExpanded,
|
||||
openConversation,
|
||||
kickOffAttachmentDownload,
|
||||
messageExpanded,
|
||||
showConversation,
|
||||
status,
|
||||
text,
|
||||
textDirection,
|
||||
textAttachment,
|
||||
textDirection,
|
||||
} = this.props;
|
||||
const { metadataWidth } = this.state;
|
||||
const isRTL = textDirection === TextDirection.RightToLeft;
|
||||
|
@ -1747,13 +1748,11 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
>
|
||||
<MessageBodyReadMore
|
||||
bodyRanges={bodyRanges}
|
||||
disableLinks={!this.areLinksEnabled()}
|
||||
direction={direction}
|
||||
disableLinks={!this.areLinksEnabled()}
|
||||
displayLimit={displayLimit}
|
||||
i18n={i18n}
|
||||
id={id}
|
||||
messageExpanded={messageExpanded}
|
||||
openConversation={openConversation}
|
||||
kickOffBodyDownload={() => {
|
||||
if (!textAttachment) {
|
||||
return;
|
||||
|
@ -1763,6 +1762,8 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
messageId: id,
|
||||
});
|
||||
}}
|
||||
messageExpanded={messageExpanded}
|
||||
showConversation={showConversation}
|
||||
text={contents || ''}
|
||||
textAttachment={textAttachment}
|
||||
/>
|
||||
|
|
|
@ -13,31 +13,27 @@ import { Emojify } from './Emojify';
|
|||
import { AddNewLines } from './AddNewLines';
|
||||
import { Linkify } from './Linkify';
|
||||
|
||||
import type { ShowConversationType } from '../../state/ducks/conversations';
|
||||
import type {
|
||||
HydratedBodyRangesType,
|
||||
LocalizerType,
|
||||
RenderTextCallbackType,
|
||||
} from '../../types/Util';
|
||||
|
||||
type OpenConversationActionType = (
|
||||
conversationId: string,
|
||||
messageId?: string
|
||||
) => void;
|
||||
|
||||
export type Props = {
|
||||
direction?: 'incoming' | 'outgoing';
|
||||
text: string;
|
||||
author?: string;
|
||||
textAttachment?: Pick<AttachmentType, 'pending' | 'digest' | 'key'>;
|
||||
bodyRanges?: HydratedBodyRangesType;
|
||||
direction?: 'incoming' | 'outgoing';
|
||||
/** If set, all emoji will be the same size. Otherwise, just one emoji will be large. */
|
||||
disableJumbomoji?: boolean;
|
||||
/** If set, links will be left alone instead of turned into clickable `<a>` tags. */
|
||||
disableLinks?: boolean;
|
||||
i18n: LocalizerType;
|
||||
bodyRanges?: HydratedBodyRangesType;
|
||||
onIncreaseTextLength?: () => unknown;
|
||||
openConversation?: OpenConversationActionType;
|
||||
kickOffBodyDownload?: () => void;
|
||||
onIncreaseTextLength?: () => unknown;
|
||||
showConversation?: ShowConversationType;
|
||||
text: string;
|
||||
textAttachment?: Pick<AttachmentType, 'pending' | 'digest' | 'key'>;
|
||||
};
|
||||
|
||||
const renderEmoji = ({
|
||||
|
@ -67,17 +63,17 @@ const renderEmoji = ({
|
|||
* them for you.
|
||||
*/
|
||||
export function MessageBody({
|
||||
author,
|
||||
bodyRanges,
|
||||
direction,
|
||||
disableJumbomoji,
|
||||
disableLinks,
|
||||
i18n,
|
||||
onIncreaseTextLength,
|
||||
openConversation,
|
||||
text,
|
||||
author,
|
||||
textAttachment,
|
||||
kickOffBodyDownload,
|
||||
onIncreaseTextLength,
|
||||
showConversation,
|
||||
text,
|
||||
textAttachment,
|
||||
}: Props): JSX.Element {
|
||||
const hasReadMore = Boolean(onIncreaseTextLength);
|
||||
const textWithSuffix =
|
||||
|
@ -100,10 +96,10 @@ export function MessageBody({
|
|||
renderNonNewLine={({ text: innerText, key: innerKey }) => (
|
||||
<AtMentionify
|
||||
key={innerKey}
|
||||
direction={direction}
|
||||
text={innerText}
|
||||
bodyRanges={bodyRanges}
|
||||
openConversation={openConversation}
|
||||
direction={direction}
|
||||
showConversation={showConversation}
|
||||
text={innerText}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -9,14 +9,14 @@ import { graphemeAndLinkAwareSlice } from '../../util/graphemeAndLinkAwareSlice'
|
|||
|
||||
export type Props = Pick<
|
||||
MessageBodyPropsType,
|
||||
| 'bodyRanges'
|
||||
| 'direction'
|
||||
| 'text'
|
||||
| 'textAttachment'
|
||||
| 'disableLinks'
|
||||
| 'i18n'
|
||||
| 'bodyRanges'
|
||||
| 'openConversation'
|
||||
| 'kickOffBodyDownload'
|
||||
| 'showConversation'
|
||||
| 'text'
|
||||
| 'textAttachment'
|
||||
> & {
|
||||
id: string;
|
||||
displayLimit?: number;
|
||||
|
@ -38,9 +38,9 @@ export function MessageBodyReadMore({
|
|||
displayLimit,
|
||||
i18n,
|
||||
id,
|
||||
messageExpanded,
|
||||
openConversation,
|
||||
kickOffBodyDownload,
|
||||
messageExpanded,
|
||||
showConversation,
|
||||
text,
|
||||
textAttachment,
|
||||
}: Props): JSX.Element {
|
||||
|
@ -61,12 +61,12 @@ export function MessageBodyReadMore({
|
|||
return (
|
||||
<MessageBody
|
||||
bodyRanges={bodyRanges}
|
||||
disableLinks={disableLinks}
|
||||
direction={direction}
|
||||
disableLinks={disableLinks}
|
||||
i18n={i18n}
|
||||
onIncreaseTextLength={onIncreaseTextLength}
|
||||
openConversation={openConversation}
|
||||
kickOffBodyDownload={kickOffBodyDownload}
|
||||
onIncreaseTextLength={onIncreaseTextLength}
|
||||
showConversation={showConversation}
|
||||
text={slicedText}
|
||||
textAttachment={textAttachment}
|
||||
/>
|
||||
|
|
|
@ -78,7 +78,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
|||
kickOffAttachmentDownload: action('kickOffAttachmentDownload'),
|
||||
markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'),
|
||||
markViewed: action('markViewed'),
|
||||
openConversation: action('openConversation'),
|
||||
showConversation: action('showConversation'),
|
||||
openGiftBadge: action('openGiftBadge'),
|
||||
openLink: action('openLink'),
|
||||
renderAudioAttachment: () => <div>*AudioAttachment*</div>,
|
||||
|
|
|
@ -81,7 +81,6 @@ export type PropsBackboneActions = Pick<
|
|||
MessagePropsType,
|
||||
| 'kickOffAttachmentDownload'
|
||||
| 'markAttachmentAsCorrupted'
|
||||
| 'openConversation'
|
||||
| 'openGiftBadge'
|
||||
| 'openLink'
|
||||
| 'renderAudioAttachment'
|
||||
|
@ -98,6 +97,7 @@ export type PropsReduxActions = Pick<
|
|||
| 'doubleCheckMissingQuoteReference'
|
||||
| 'saveAttachment'
|
||||
| 'showContactModal'
|
||||
| 'showConversation'
|
||||
| 'showLightbox'
|
||||
| 'showLightboxForViewOnceMedia'
|
||||
| 'viewStory'
|
||||
|
@ -290,13 +290,13 @@ export class MessageDetail extends React.Component<Props> {
|
|||
kickOffAttachmentDownload,
|
||||
markAttachmentAsCorrupted,
|
||||
markViewed,
|
||||
openConversation,
|
||||
openGiftBadge,
|
||||
openLink,
|
||||
renderAudioAttachment,
|
||||
saveAttachment,
|
||||
showContactDetail,
|
||||
showContactModal,
|
||||
showConversation,
|
||||
showExpiredIncomingTapToViewToast,
|
||||
showExpiredOutgoingTapToViewToast,
|
||||
showLightbox,
|
||||
|
@ -336,7 +336,7 @@ export class MessageDetail extends React.Component<Props> {
|
|||
markAttachmentAsCorrupted={markAttachmentAsCorrupted}
|
||||
markViewed={markViewed}
|
||||
messageExpanded={noop}
|
||||
openConversation={openConversation}
|
||||
showConversation={showConversation}
|
||||
openGiftBadge={openGiftBadge}
|
||||
openLink={openLink}
|
||||
renderAudioAttachment={renderAudioAttachment}
|
||||
|
|
|
@ -112,7 +112,7 @@ const defaultMessageProps: TimelineMessagesProps = {
|
|||
markAttachmentAsCorrupted: action('default--markAttachmentAsCorrupted'),
|
||||
markViewed: action('default--markViewed'),
|
||||
messageExpanded: action('default--message-expanded'),
|
||||
openConversation: action('default--openConversation'),
|
||||
showConversation: action('default--showConversation'),
|
||||
openGiftBadge: action('openGiftBadge'),
|
||||
openLink: action('default--openLink'),
|
||||
previews: [],
|
||||
|
|
|
@ -282,10 +282,10 @@ const actions = () => ({
|
|||
deleteMessage: action('deleteMessage'),
|
||||
deleteMessageForEveryone: action('deleteMessageForEveryone'),
|
||||
showMessageDetail: action('showMessageDetail'),
|
||||
openConversation: action('openConversation'),
|
||||
saveAttachment: action('saveAttachment'),
|
||||
showContactDetail: action('showContactDetail'),
|
||||
showContactModal: action('showContactModal'),
|
||||
showConversation: action('showConversation'),
|
||||
kickOffAttachmentDownload: action('kickOffAttachmentDownload'),
|
||||
markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'),
|
||||
markViewed: action('markViewed'),
|
||||
|
|
|
@ -244,8 +244,8 @@ const getActions = createSelector(
|
|||
'toggleForwardMessageModal',
|
||||
'deleteMessage',
|
||||
'deleteMessageForEveryone',
|
||||
'showConversation',
|
||||
'showMessageDetail',
|
||||
'openConversation',
|
||||
'openGiftBadge',
|
||||
'setQuoteByMessageId',
|
||||
'showContactDetail',
|
||||
|
|
|
@ -78,7 +78,7 @@ const getDefaultProps = () => ({
|
|||
markViewed: action('markViewed'),
|
||||
messageExpanded: action('messageExpanded'),
|
||||
showMessageDetail: action('showMessageDetail'),
|
||||
openConversation: action('openConversation'),
|
||||
showConversation: action('showConversation'),
|
||||
openGiftBadge: action('openGiftBadge'),
|
||||
saveAttachment: action('saveAttachment'),
|
||||
showContactDetail: action('showContactDetail'),
|
||||
|
|
|
@ -279,7 +279,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
|||
markAttachmentAsCorrupted: action('markAttachmentAsCorrupted'),
|
||||
markViewed: action('markViewed'),
|
||||
messageExpanded: action('messageExpanded'),
|
||||
openConversation: action('openConversation'),
|
||||
showConversation: action('showConversation'),
|
||||
openGiftBadge: action('openGiftBadge'),
|
||||
openLink: action('openLink'),
|
||||
previews: overrideProps.previews || [],
|
||||
|
|
|
@ -44,6 +44,7 @@ import {
|
|||
getLinkPreviewForSend,
|
||||
hasLinkPreviewLoaded,
|
||||
maybeGrabLinkPreview,
|
||||
removeLinkPreview,
|
||||
resetLinkPreview,
|
||||
} from '../../services/LinkPreview';
|
||||
import { getMaximumAttachmentSize } from '../../util/attachments';
|
||||
|
@ -789,6 +790,10 @@ function replaceAttachments(
|
|||
return;
|
||||
}
|
||||
|
||||
if (hasDraftAttachments(attachments, { includePending: true })) {
|
||||
removeLinkPreview();
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: REPLACE_ATTACHMENTS,
|
||||
payload: attachments.map(resolveDraftAttachmentOnDisk),
|
||||
|
|
|
@ -2860,7 +2860,9 @@ type ShowConversationArgsType = {
|
|||
messageId?: string;
|
||||
switchToAssociatedView?: boolean;
|
||||
};
|
||||
export type ShowConversationType = (_: ShowConversationArgsType) => unknown;
|
||||
export type ShowConversationType = (
|
||||
options: ShowConversationArgsType
|
||||
) => unknown;
|
||||
|
||||
function showConversation({
|
||||
conversationId,
|
||||
|
|
|
@ -29,7 +29,6 @@ export type PropsType = {
|
|||
| 'onEditorStateChange'
|
||||
| 'onSelectMediaQuality'
|
||||
| 'onTextTooLong'
|
||||
| 'openConversation'
|
||||
>;
|
||||
conversationHeaderProps: ConversationHeaderPropsType;
|
||||
timelineProps: TimelinePropsType;
|
||||
|
|
|
@ -25,6 +25,7 @@ export type OwnProps = Omit<
|
|||
| 'renderReactionPicker'
|
||||
| 'theme'
|
||||
| 'showContactModal'
|
||||
| 'showConversation'
|
||||
| 'markViewed'
|
||||
>;
|
||||
|
||||
|
@ -41,7 +42,6 @@ const mapStateToProps = (
|
|||
|
||||
kickOffAttachmentDownload,
|
||||
markAttachmentAsCorrupted,
|
||||
openConversation,
|
||||
openGiftBadge,
|
||||
openLink,
|
||||
showContactDetail,
|
||||
|
@ -76,7 +76,6 @@ const mapStateToProps = (
|
|||
kickOffAttachmentDownload,
|
||||
markAttachmentAsCorrupted,
|
||||
markViewed,
|
||||
openConversation,
|
||||
openGiftBadge,
|
||||
openLink,
|
||||
renderAudioAttachment,
|
||||
|
|
|
@ -74,7 +74,6 @@ export type TimelinePropsType = ExternalProps &
|
|||
| 'loadOlderMessages'
|
||||
| 'markAttachmentAsCorrupted'
|
||||
| 'markMessageRead'
|
||||
| 'openConversation'
|
||||
| 'openGiftBadge'
|
||||
| 'openLink'
|
||||
| 'reactToMessage'
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import type { ReduxActions } from '../../../state/types';
|
||||
import { actions, getEmptyState, reducer } from '../../../state/ducks/composer';
|
||||
import { noopAction } from '../../../state/ducks/noop';
|
||||
import { reducer as rootReducer } from '../../../state/reducer';
|
||||
|
@ -38,6 +40,22 @@ describe('both/state/ducks/composer', () => {
|
|||
};
|
||||
|
||||
describe('replaceAttachments', () => {
|
||||
let oldReduxActions: ReduxActions;
|
||||
before(() => {
|
||||
oldReduxActions = window.reduxActions;
|
||||
window.reduxActions = {
|
||||
...oldReduxActions,
|
||||
linkPreviews: {
|
||||
...oldReduxActions?.linkPreviews,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
removeLinkPreview: noop as any,
|
||||
},
|
||||
};
|
||||
});
|
||||
after(() => {
|
||||
window.reduxActions = oldReduxActions;
|
||||
});
|
||||
|
||||
it('replaces the attachments state', () => {
|
||||
const { replaceAttachments } = actions;
|
||||
const dispatch = sinon.spy();
|
||||
|
|
|
@ -26,7 +26,6 @@ import type { ConversationType } from '../state/ducks/conversations';
|
|||
import { calling } from '../services/calling';
|
||||
import { getConversationsWithCustomColorSelector } from '../state/selectors/conversations';
|
||||
import { getCustomColors } from '../state/selectors/items';
|
||||
import { trigger } from '../shims/events';
|
||||
import { themeChanged } from '../shims/themeChanged';
|
||||
import { renderClearingDataView } from '../shims/renderClearingDataView';
|
||||
|
||||
|
@ -491,7 +490,9 @@ export function createIPCEvents(
|
|||
setIsFetchingUUID: noop,
|
||||
});
|
||||
if (convoId) {
|
||||
trigger('showConversation', convoId);
|
||||
window.reduxActions.conversations.showConversation({
|
||||
conversationId: convoId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// We will show not found modal on error
|
||||
|
@ -507,7 +508,9 @@ export function createIPCEvents(
|
|||
setIsFetchingUUID: noop,
|
||||
});
|
||||
if (convoId) {
|
||||
trigger('showConversation', convoId);
|
||||
window.reduxActions.conversations.showConversation({
|
||||
conversationId: convoId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// We will show not found modal on error
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import type { AttachmentDraftType } from '../types/Attachment';
|
||||
|
||||
export function hasDraftAttachments(
|
||||
draftAttachments: Array<AttachmentDraftType> | undefined,
|
||||
draftAttachments: ReadonlyArray<AttachmentDraftType> | undefined,
|
||||
options: { includePending: boolean }
|
||||
): boolean {
|
||||
if (!draftAttachments) {
|
||||
|
|
|
@ -15,5 +15,7 @@ export function startConversation(e164: string, uuid: UUIDStringType): void {
|
|||
`startConversation failed given ${e164}/${uuid} combination`
|
||||
);
|
||||
|
||||
window.Whisper.events.trigger('showConversation', conversation.id);
|
||||
window.reduxActions.conversations.showConversation({
|
||||
conversationId: conversation.id,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import { ToastReactionFailed } from '../components/ToastReactionFailed';
|
|||
import { ToastTapToViewExpiredIncoming } from '../components/ToastTapToViewExpiredIncoming';
|
||||
import { ToastTapToViewExpiredOutgoing } from '../components/ToastTapToViewExpiredOutgoing';
|
||||
import { ToastCannotOpenGiftBadge } from '../components/ToastCannotOpenGiftBadge';
|
||||
import { deleteDraftAttachment } from '../util/deleteDraftAttachment';
|
||||
import { retryMessageSend } from '../util/retryMessageSend';
|
||||
import { isNotNil } from '../util/isNotNil';
|
||||
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
|
||||
|
@ -55,7 +54,7 @@ import {
|
|||
import { SECOND } from '../util/durations';
|
||||
import { startConversation } from '../util/startConversation';
|
||||
import { longRunningTaskWrapper } from '../util/longRunningTaskWrapper';
|
||||
import { hasDraftAttachments } from '../util/hasDraftAttachments';
|
||||
import { clearConversationDraftAttachments } from '../util/clearConversationDraftAttachments';
|
||||
import type { BackbonePanelRenderType, PanelRenderType } from '../types/Panels';
|
||||
import { PanelType, isPanelHandledByReact } from '../types/Panels';
|
||||
|
||||
|
@ -80,7 +79,6 @@ type MessageActionsType = {
|
|||
options: Readonly<{ messageId: string }>
|
||||
) => unknown;
|
||||
markAttachmentAsCorrupted: (options: AttachmentOptions) => unknown;
|
||||
openConversation: (conversationId: string, messageId?: string) => unknown;
|
||||
openGiftBadge: (messageId: string) => unknown;
|
||||
openLink: (url: string) => unknown;
|
||||
reactToMessage: (
|
||||
|
@ -150,27 +148,18 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
this.listenTo(this.model, 'show-message-details', this.showMessageDetail);
|
||||
this.listenTo(this.model, 'delete-message', this.deleteMessage);
|
||||
this.listenTo(this.model, 'remove-link-review', removeLinkPreview);
|
||||
this.listenTo(
|
||||
this.model,
|
||||
'remove-all-draft-attachments',
|
||||
this.clearAttachments
|
||||
);
|
||||
|
||||
this.listenTo(this.model, 'pushPanel', this.pushPanel);
|
||||
this.listenTo(this.model, 'popPanel', this.popPanel);
|
||||
|
||||
this.render();
|
||||
|
||||
this.setupConversationView();
|
||||
this.updateAttachmentsView();
|
||||
|
||||
this.listenTo(this.model, 'pushPanel', this.pushPanel);
|
||||
this.listenTo(this.model, 'popPanel', this.popPanel);
|
||||
}
|
||||
|
||||
override events(): Record<string, string> {
|
||||
return {
|
||||
drop: 'onDrop',
|
||||
paste: 'onPaste',
|
||||
};
|
||||
window.reduxActions.composer.replaceAttachments(
|
||||
this.model.get('id'),
|
||||
this.model.get('draftAttachments') || []
|
||||
);
|
||||
}
|
||||
|
||||
// We need this ignore because the backbone types really want this to be a string
|
||||
|
@ -231,7 +220,9 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
showToast(ToastConversationArchived, {
|
||||
undo: () => {
|
||||
this.model.setArchived(false);
|
||||
this.openConversation(this.model.get('id'));
|
||||
window.reduxActions.conversations.showConversation({
|
||||
conversationId: this.model.id,
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
@ -373,7 +364,11 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
},
|
||||
|
||||
onClearAttachments: this.clearAttachments.bind(this),
|
||||
onClearAttachments: () =>
|
||||
clearConversationDraftAttachments(
|
||||
this.model.id,
|
||||
this.model.get('draftAttachments')
|
||||
),
|
||||
onSelectMediaQuality: (isHQ: boolean) => {
|
||||
window.reduxActions.composer.setMediaQualitySetting(isHQ);
|
||||
},
|
||||
|
@ -382,8 +377,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
suspendLinkPreviews();
|
||||
removeLinkPreview();
|
||||
},
|
||||
|
||||
openConversation: this.openConversation.bind(this),
|
||||
};
|
||||
|
||||
// createConversationView root
|
||||
|
@ -423,9 +416,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
const showMessageDetail = (messageId: string) => {
|
||||
this.showMessageDetail(messageId);
|
||||
};
|
||||
const openConversation = (conversationId: string, messageId?: string) => {
|
||||
this.openConversation(conversationId, messageId);
|
||||
};
|
||||
const showContactDetail = (options: {
|
||||
contact: EmbeddedContactType;
|
||||
signalAccount?: {
|
||||
|
@ -485,7 +475,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
downloadNewVersion,
|
||||
kickOffAttachmentDownload,
|
||||
markAttachmentAsCorrupted,
|
||||
openConversation,
|
||||
openGiftBadge,
|
||||
openLink,
|
||||
reactToMessage,
|
||||
|
@ -530,8 +519,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
});
|
||||
}
|
||||
|
||||
// We don't wait here; we need to take down the view
|
||||
this.saveModel();
|
||||
window.Signal.Data.updateConversation(this.model.attributes);
|
||||
|
||||
this.model.updateLastMessage();
|
||||
}
|
||||
|
@ -560,10 +548,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
this.remove();
|
||||
}
|
||||
|
||||
async saveModel(): Promise<void> {
|
||||
window.Signal.Data.updateConversation(this.model.attributes);
|
||||
}
|
||||
|
||||
async onOpened(messageId: string): Promise<void> {
|
||||
this.model.onOpenStart();
|
||||
|
||||
|
@ -1171,17 +1155,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
return view;
|
||||
}
|
||||
|
||||
async openConversation(
|
||||
conversationId: string,
|
||||
messageId?: string
|
||||
): Promise<void> {
|
||||
window.Whisper.events.trigger(
|
||||
'showConversation',
|
||||
conversationId,
|
||||
messageId
|
||||
);
|
||||
}
|
||||
|
||||
pushPanel(panel: PanelRenderType): void {
|
||||
if (isPanelHandledByReact(panel)) {
|
||||
return;
|
||||
|
@ -1286,35 +1259,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
|||
// Backup, in case things go wrong with the transitionend event
|
||||
timeout = setTimeout(removePanel, SECOND);
|
||||
}
|
||||
|
||||
async clearAttachments(): Promise<void> {
|
||||
const draftAttachments = this.model.get('draftAttachments') || [];
|
||||
this.model.set({
|
||||
draftAttachments: [],
|
||||
draftChanged: true,
|
||||
});
|
||||
|
||||
this.updateAttachmentsView();
|
||||
|
||||
// We're fine doing this all at once; at most it should be 32 attachments
|
||||
await Promise.all([
|
||||
this.saveModel(),
|
||||
Promise.all(
|
||||
draftAttachments.map(attachment => deleteDraftAttachment(attachment))
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
updateAttachmentsView(): void {
|
||||
const draftAttachments = this.model.get('draftAttachments') || [];
|
||||
window.reduxActions.composer.replaceAttachments(
|
||||
this.model.get('id'),
|
||||
draftAttachments
|
||||
);
|
||||
if (hasDraftAttachments(this.model.attributes, { includePending: true })) {
|
||||
removeLinkPreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.Whisper.ConversationView = ConversationView;
|
||||
|
|
Loading…
Add table
Reference in a new issue