Standardize on showConversation function, delete unused functions

This commit is contained in:
Scott Nonnenberg 2022-12-14 11:05:32 -08:00 committed by GitHub
parent 1dc3ed914f
commit f2f1c3c021
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 174 additions and 198 deletions

View file

@ -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();

View file

@ -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>
)}

View file

@ -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}
/>
))}

View file

@ -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,

View file

@ -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}
/>
);

View file

@ -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]);

View file

@ -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]}

View file

@ -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(

View file

@ -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);

View file

@ -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>

View file

@ -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: [],

View file

@ -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 || ''),
});

View file

@ -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}

View file

@ -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 {

View file

@ -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;
};

View file

@ -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}
/>

View file

@ -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}
/>
)}
/>

View file

@ -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}
/>

View file

@ -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>,

View file

@ -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}

View file

@ -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: [],

View file

@ -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'),

View file

@ -244,8 +244,8 @@ const getActions = createSelector(
'toggleForwardMessageModal',
'deleteMessage',
'deleteMessageForEveryone',
'showConversation',
'showMessageDetail',
'openConversation',
'openGiftBadge',
'setQuoteByMessageId',
'showContactDetail',

View file

@ -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'),

View file

@ -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 || [],

View file

@ -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),

View file

@ -2860,7 +2860,9 @@ type ShowConversationArgsType = {
messageId?: string;
switchToAssociatedView?: boolean;
};
export type ShowConversationType = (_: ShowConversationArgsType) => unknown;
export type ShowConversationType = (
options: ShowConversationArgsType
) => unknown;
function showConversation({
conversationId,

View file

@ -29,7 +29,6 @@ export type PropsType = {
| 'onEditorStateChange'
| 'onSelectMediaQuality'
| 'onTextTooLong'
| 'openConversation'
>;
conversationHeaderProps: ConversationHeaderPropsType;
timelineProps: TimelinePropsType;

View file

@ -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,

View file

@ -74,7 +74,6 @@ export type TimelinePropsType = ExternalProps &
| 'loadOlderMessages'
| 'markAttachmentAsCorrupted'
| 'markMessageRead'
| 'openConversation'
| 'openGiftBadge'
| 'openLink'
| 'reactToMessage'

View file

@ -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();

View file

@ -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

View file

@ -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) {

View file

@ -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,
});
}

View file

@ -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;