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