Use useCallback all the time in smart components

This commit is contained in:
Jamie Kyle 2024-03-19 10:12:32 -07:00 committed by GitHub
parent ffb1fe2590
commit 193f344b16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 319 additions and 195 deletions

View file

@ -11,11 +11,11 @@ import { SmartGlobalModalContainer } from './GlobalModalContainer';
import { SmartLightbox } from './Lightbox';
import { SmartStoryViewer } from './StoryViewer';
import {
getTheme,
getIsMainWindowMaximized,
getIsMainWindowFullScreen,
getTheme,
} from '../selectors/user';
import { hasSelectedStoryData } from '../selectors/stories';
import { hasSelectedStoryData as getHasSelectedStoryData } from '../selectors/stories';
import { useAppActions } from '../ducks/app';
import { useConversationsActions } from '../ducks/conversations';
import { useStoriesActions } from '../ducks/stories';
@ -28,53 +28,78 @@ function renderInbox(): JSX.Element {
return <SmartInbox />;
}
function renderCallManager(): JSX.Element {
return (
<ModalContainer className="module-calling__modal-container">
<SmartCallManager />
</ModalContainer>
);
}
function renderGlobalModalContainer(): JSX.Element {
return <SmartGlobalModalContainer />;
}
function renderLightbox(): JSX.Element {
return <SmartLightbox />;
}
function renderStoryViewer(closeView: () => unknown): JSX.Element {
return (
<ErrorBoundary name="App/renderStoryViewer" closeView={closeView}>
<SmartStoryViewer />
</ErrorBoundary>
);
}
function requestVerification(
number: string,
captcha: string,
transport: VerificationTransport
): Promise<{ sessionId: string }> {
const { server } = window.textsecure;
strictAssert(server !== undefined, 'WebAPI not available');
return server.requestVerification(number, captcha, transport);
}
function registerSingleDevice(
number: string,
code: string,
sessionId: string
): Promise<void> {
return window
.getAccountManager()
.registerSingleDevice(number, code, sessionId);
}
export const SmartApp = memo(function SmartApp() {
const appView = useSelector(getAppView);
const isMaximized = useSelector(getIsMainWindowMaximized);
const isFullScreen = useSelector(getIsMainWindowFullScreen);
const hasSelectedStoryData = useSelector(getHasSelectedStoryData);
const theme = useSelector(getTheme);
const { openInbox } = useAppActions();
const { scrollToMessage } = useConversationsActions();
const { viewStory } = useStoriesActions();
const osClassName = OS.getClassName();
return (
<App
appView={appView}
isMaximized={useSelector(getIsMainWindowMaximized)}
isFullScreen={useSelector(getIsMainWindowFullScreen)}
osClassName={OS.getClassName()}
renderCallManager={() => (
<ModalContainer className="module-calling__modal-container">
<SmartCallManager />
</ModalContainer>
)}
renderGlobalModalContainer={() => <SmartGlobalModalContainer />}
renderLightbox={() => <SmartLightbox />}
hasSelectedStoryData={useSelector(hasSelectedStoryData)}
renderStoryViewer={(closeView: () => unknown) => (
<ErrorBoundary name="App/renderStoryViewer" closeView={closeView}>
<SmartStoryViewer />
</ErrorBoundary>
)}
isMaximized={isMaximized}
isFullScreen={isFullScreen}
osClassName={osClassName}
renderCallManager={renderCallManager}
renderGlobalModalContainer={renderGlobalModalContainer}
renderLightbox={renderLightbox}
hasSelectedStoryData={hasSelectedStoryData}
renderStoryViewer={renderStoryViewer}
renderInbox={renderInbox}
requestVerification={(
number: string,
captcha: string,
transport: VerificationTransport
): Promise<{ sessionId: string }> => {
const { server } = window.textsecure;
strictAssert(server !== undefined, 'WebAPI not available');
return server.requestVerification(number, captcha, transport);
}}
registerSingleDevice={(
number: string,
code: string,
sessionId: string
): Promise<void> => {
return window
.getAccountManager()
.registerSingleDevice(number, code, sessionId);
}}
theme={useSelector(getTheme)}
requestVerification={requestVerification}
registerSingleDevice={registerSingleDevice}
theme={theme}
openInbox={openInbox}
scrollToMessage={scrollToMessage}
viewStory={viewStory}

View file

@ -4,7 +4,6 @@
import React, { memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { CompositionRecording } from '../../components/CompositionRecording';
import { mapDispatchToProps } from '../actions';
import { useAudioRecorderActions } from '../ducks/audioRecorder';
import { useComposerActions } from '../ducks/composer';
import { useToastActions } from '../ducks/toast';
@ -21,9 +20,10 @@ export const SmartCompositionRecording = memo(
}: SmartCompositionRecordingProps) {
const i18n = useSelector(getIntl);
const selectedConversationId = useSelector(getSelectedConversationId);
const { cancelRecording, completeRecording } = useAudioRecorderActions();
const { errorRecording, cancelRecording, completeRecording } =
useAudioRecorderActions();
const { sendMultiMediaMessage } = useComposerActions();
const { sendMultiMediaMessage, addAttachment } = useComposerActions();
const { hideToast, showToast } = useToastActions();
const handleCancel = useCallback(() => {
@ -56,9 +56,9 @@ export const SmartCompositionRecording = memo(
conversationId={selectedConversationId}
onCancel={handleCancel}
onSend={handleSend}
errorRecording={mapDispatchToProps.errorRecording}
addAttachment={mapDispatchToProps.addAttachment}
completeRecording={mapDispatchToProps.completeRecording}
errorRecording={errorRecording}
addAttachment={addAttachment}
completeRecording={completeRecording}
showToast={showToast}
hideToast={hideToast}
/>

View file

@ -1,6 +1,6 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { strictAssert } from '../../util/assert';
import { ConfirmAdditionsModal } from '../../components/conversation/conversation-details/AddGroupMembersModal/ConfirmAdditionsModal';
@ -27,14 +27,16 @@ export const SmartConfirmAdditionsModal = memo(
const i18n = useSelector(getIntl);
const conversationSelector = useSelector(getConversationByIdSelector);
const selectedContacts = selectedConversationIds.map(conversationId => {
const convo = conversationSelector(conversationId);
strictAssert(
convo,
'<SmartChooseGroupMemberModal> selected conversation not found'
);
return convo;
});
const selectedContacts = useMemo(() => {
return selectedConversationIds.map(conversationId => {
const convo = conversationSelector(conversationId);
strictAssert(
convo,
'<SmartChooseGroupMemberModal> selected conversation not found'
);
return convo;
});
}, [conversationSelector, selectedConversationIds]);
return (
<ConfirmAdditionsModal

View file

@ -1,6 +1,6 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo } from 'react';
import React, { memo, useCallback, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { ContactName } from '../../components/conversation/ContactName';
import { getIntl } from '../selectors/user';
@ -14,26 +14,28 @@ type ExternalProps = {
contactId: string;
};
export const SmartContactName = memo(function SmartContactName(
props: ExternalProps
) {
const { contactId } = props;
export const SmartContactName = memo(function SmartContactName({
contactId,
}: ExternalProps) {
const i18n = useSelector(getIntl);
const getConversation = useSelector(getConversationSelector);
const contact = getConversation(contactId) || {
title: i18n('icu:unknownContact'),
};
const currentConversationId = useSelector(getSelectedConversationId);
const currentConversation = getConversation(currentConversationId);
const { showContactModal } = useGlobalModalActions();
const contact = useMemo(() => {
return getConversation(contactId);
}, [getConversation, contactId]);
const handleClick = useCallback(() => {
showContactModal(contactId, currentConversationId);
}, [showContactModal, contactId, currentConversationId]);
return (
<ContactName
firstName={contact.firstName}
title={contact.title}
onClick={() => showContactModal(contact.id, currentConversation.id)}
title={contact.title ?? i18n('icu:unknownContact')}
onClick={handleClick}
/>
);
});

View file

@ -43,27 +43,41 @@ export const SmartDeleteMessagesModal = memo(
useConversationsActions();
const { showToast } = useToastActions();
const messageCount = deleteMessagesProps.messageIds.length;
const handleClose = useCallback(() => {
toggleDeleteMessagesModal(undefined);
}, [toggleDeleteMessagesModal]);
const handleDeleteForMe = useCallback(() => {
deleteMessages({
conversationId,
messageIds,
lastSelectedMessage,
});
onDelete?.();
}, [
conversationId,
deleteMessages,
lastSelectedMessage,
messageIds,
onDelete,
]);
const handleDeleteForEveryone = useCallback(() => {
deleteMessagesForEveryone(messageIds);
onDelete?.();
}, [deleteMessagesForEveryone, messageIds, onDelete]);
return (
<DeleteMessagesModal
isMe={isMe}
canDeleteForEveryone={canDeleteForEveryone}
i18n={i18n}
messageCount={deleteMessagesProps.messageIds.length}
onClose={() => {
toggleDeleteMessagesModal(undefined);
}}
onDeleteForMe={() => {
deleteMessages({
conversationId,
messageIds,
lastSelectedMessage,
});
onDelete?.();
}}
onDeleteForEveryone={() => {
deleteMessagesForEveryone(messageIds);
onDelete?.();
}}
messageCount={messageCount}
onClose={handleClose}
onDeleteForMe={handleDeleteForMe}
onDeleteForEveryone={handleDeleteForEveryone}
showToast={showToast}
/>
);

View file

@ -1,7 +1,7 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { forwardRef, memo } from 'react';
import React, { useCallback, forwardRef, memo } from 'react';
import { useSelector } from 'react-redux';
import { useRecentEmojis } from '../selectors/emojis';
import { useEmojisActions as useEmojiActions } from '../ducks/emojis';
@ -25,10 +25,9 @@ export const SmartEmojiPicker = memo(
const skinTone = useSelector(getEmojiSkinTone);
const recentEmojis = useRecentEmojis();
const { onUseEmoji } = useEmojiActions();
const handlePickEmoji = React.useCallback(
const handlePickEmoji = useCallback(
data => {
onUseEmoji({ shortName: data.shortName });
onPickEmoji(data);

View file

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { useSelector } from 'react-redux';
import type {
ForwardMessagePropsType,
@ -100,67 +100,83 @@ function SmartForwardMessagesModalInner({
}
);
if (!drafts.length) {
return null;
}
const handleChange = useCallback(
(
updatedDrafts: ReadonlyArray<MessageForwardDraft>,
caretLocation?: number
) => {
setDrafts(updatedDrafts);
const isLonelyDraft = updatedDrafts.length === 1;
const lonelyDraft = isLonelyDraft ? updatedDrafts[0] : null;
if (lonelyDraft == null) {
return;
}
const attachmentsLength = lonelyDraft.attachments?.length ?? 0;
if (attachmentsLength === 0) {
maybeGrabLinkPreview(
lonelyDraft.messageBody ?? '',
LinkPreviewSourceType.ForwardMessageModal,
{ caretLocation }
);
}
},
[]
);
function closeModal() {
const closeModal = useCallback(() => {
resetLinkPreview();
toggleForwardMessagesModal();
}, [toggleForwardMessagesModal]);
const doForwardMessages = useCallback(
async (
conversationIds: ReadonlyArray<string>,
finalDrafts: ReadonlyArray<MessageForwardDraft>
) => {
try {
const messages = await Promise.all(
finalDrafts.map(async (draft): Promise<ForwardMessageData> => {
const message = await __DEPRECATED$getMessageById(
draft.originalMessageId
);
strictAssert(message, 'no message found');
return {
draft,
originalMessage: message.attributes,
};
})
);
const didForwardSuccessfully = await maybeForwardMessages(
messages,
conversationIds
);
if (didForwardSuccessfully) {
closeModal();
forwardMessagesProps?.onForward?.();
}
} catch (err) {
log.warn('doForwardMessage', Errors.toLogFormat(err));
}
},
[forwardMessagesProps, closeModal]
);
if (!drafts.length) {
return null;
}
return (
<ForwardMessagesModal
drafts={drafts}
candidateConversations={candidateConversations}
doForwardMessages={async (conversationIds, finalDrafts) => {
try {
const messages = await Promise.all(
finalDrafts.map(async (draft): Promise<ForwardMessageData> => {
const message = await __DEPRECATED$getMessageById(
draft.originalMessageId
);
strictAssert(message, 'no message found');
return {
draft,
originalMessage: message.attributes,
};
})
);
const didForwardSuccessfully = await maybeForwardMessages(
messages,
conversationIds
);
if (didForwardSuccessfully) {
closeModal();
forwardMessagesProps?.onForward?.();
}
} catch (err) {
log.warn('doForwardMessage', Errors.toLogFormat(err));
}
}}
doForwardMessages={doForwardMessages}
linkPreviewForSource={linkPreviewForSource}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
onClose={closeModal}
onChange={(updatedDrafts, caretLocation) => {
setDrafts(updatedDrafts);
const isLonelyDraft = updatedDrafts.length === 1;
const lonelyDraft = isLonelyDraft ? updatedDrafts[0] : null;
if (lonelyDraft == null) {
return;
}
const attachmentsLength = lonelyDraft.attachments?.length ?? 0;
if (attachmentsLength === 0) {
maybeGrabLinkPreview(
lonelyDraft.messageBody ?? '',
LinkPreviewSourceType.ForwardMessageModal,
{ caretLocation }
);
}
}}
onChange={handleChange}
regionCode={regionCode}
RenderCompositionTextArea={SmartCompositionTextArea}
removeLinkPreview={removeLinkPreview}

View file

@ -49,14 +49,14 @@ export const SmartMiniPlayer = memo(function SmartMiniPlayer({
state = active.playing ? PlayerState.playing : PlayerState.paused;
}
const title = AudioPlayerContent.isDraft(content)
? i18n('icu:you')
: getVoiceNoteTitle(content.current);
return (
<MiniPlayer
i18n={i18n}
title={
AudioPlayerContent.isDraft(content)
? i18n('icu:you')
: getVoiceNoteTitle(content.current)
}
title={title}
onPlay={handlePlay}
onPause={handlePause}
onPlaybackRate={setPlaybackRate}

View file

@ -1,9 +1,10 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import * as SingleServePromise from '../../services/singleServePromise';
import type { SafetyNumberProps } from '../../components/SafetyNumberChangeDialog';
import {
SafetyNumberChangeDialog,
SafetyNumberChangeSource,
@ -17,6 +18,10 @@ import { useGlobalModalActions } from '../ducks/globalModals';
import { useStoryDistributionListsActions } from '../ducks/storyDistributionLists';
import { getSafetyNumberChangedBlockingData } from '../selectors/globalModals';
function renderSafetyNumber({ contactID, onClose }: SafetyNumberProps) {
return <SmartSafetyNumberViewer contactID={contactID} onClose={onClose} />;
}
export const SmartSendAnywayDialog = memo(
function SmartSendAnywayDialog(): JSX.Element {
const { hideBlockingSafetyNumberChangeDialog } = useGlobalModalActions();
@ -59,26 +64,36 @@ export const SmartSendAnywayDialog = memo(
confirmText = undefined;
}
const handleCancel = useCallback(() => {
cancelConversationVerification();
explodedPromise?.resolve(false);
hideBlockingSafetyNumberChangeDialog();
}, [
cancelConversationVerification,
explodedPromise,
hideBlockingSafetyNumberChangeDialog,
]);
const handleConfirm = useCallback(() => {
verifyConversationsStoppingSend();
explodedPromise?.resolve(true);
hideBlockingSafetyNumberChangeDialog();
}, [
verifyConversationsStoppingSend,
explodedPromise,
hideBlockingSafetyNumberChangeDialog,
]);
return (
<SafetyNumberChangeDialog
confirmText={confirmText}
contacts={contacts}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
onCancel={() => {
cancelConversationVerification();
explodedPromise?.resolve(false);
hideBlockingSafetyNumberChangeDialog();
}}
onConfirm={() => {
verifyConversationsStoppingSend();
explodedPromise?.resolve(true);
hideBlockingSafetyNumberChangeDialog();
}}
onCancel={handleCancel}
onConfirm={handleConfirm}
removeFromStory={removeMembersFromDistributionList}
renderSafetyNumber={({ contactID, onClose }) => (
<SmartSafetyNumberViewer contactID={contactID} onClose={onClose} />
)}
renderSafetyNumber={renderSafetyNumber}
theme={theme}
/>
);

View file

@ -1,7 +1,7 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo, useEffect } from 'react';
import React, { memo, useCallback, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { SmartStoryCreator } from './StoryCreator';
import { SmartToastManager } from './ToastManager';
@ -33,6 +33,7 @@ import { useItemsActions } from '../ducks/items';
import { getHasPendingUpdate } from '../selectors/updates';
import { getOtherTabsUnreadStats } from '../selectors/nav';
import { getIsStoriesSettingsVisible } from '../selectors/globalModals';
import type { StoryViewType } from '../../types/Stories';
function renderStoryCreator(): JSX.Element {
return <SmartStoryCreator />;
@ -92,6 +93,22 @@ export const SmartStoriesTab = memo(function SmartStoriesTab() {
};
}, [storiesActions]);
const handleForwardStory = useCallback(
(messageId: string) => {
toggleForwardMessagesModal([messageId]);
},
[toggleForwardMessagesModal]
);
const handleSaveStory = useCallback(
(story: StoryViewType) => {
if (story.attachment) {
saveAttachment(story.attachment, story.timestamp);
}
},
[saveAttachment]
);
return (
<StoriesTab
otherTabsUnreadStats={otherTabsUnreadStats}
@ -105,14 +122,8 @@ export const SmartStoriesTab = memo(function SmartStoriesTab() {
me={me}
myStories={myStories}
navTabsCollapsed={navTabsCollapsed}
onForwardStory={messageId => {
toggleForwardMessagesModal([messageId]);
}}
onSaveStory={story => {
if (story.attachment) {
saveAttachment(story.attachment, story.timestamp);
}
}}
onForwardStory={handleForwardStory}
onSaveStory={handleSaveStory}
onToggleNavTabsCollapse={toggleNavTabsCollapse}
onMediaPlaybackStart={pauseVoiceNotePlayer}
preferredLeftPaneWidth={preferredLeftPaneWidth}

View file

@ -1,7 +1,7 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { ThemeType } from '../../types/Util';
import { LinkPreviewSourceType } from '../../types/LinkPreview';
@ -104,6 +104,10 @@ export const SmartStoryCreator = memo(function SmartStoryCreator() {
const isFormattingEnabled = useSelector(getTextFormattingEnabled);
const platform = useSelector(getPlatform);
const linkPreview = useMemo(() => {
return linkPreviewForSource(LinkPreviewSourceType.StoryCreator);
}, [linkPreviewForSource]);
return (
<StoryCreator
candidateConversations={candidateConversations}
@ -119,7 +123,7 @@ export const SmartStoryCreator = memo(function SmartStoryCreator() {
installedPacks={installedPacks}
isFormattingEnabled={isFormattingEnabled}
isSending={isSending}
linkPreview={linkPreviewForSource(LinkPreviewSourceType.StoryCreator)}
linkPreview={linkPreview}
me={me}
mostRecentActiveStoryTimestampByGroupOrDistributionList={
mostRecentActiveStoryTimestampByGroupOrDistributionList

View file

@ -1,7 +1,7 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { StoryViewer } from '../../components/StoryViewer';
import { ToastType } from '../../types/Toast';
@ -23,7 +23,7 @@ import {
getHasAllStoriesUnmuted,
} from '../selectors/stories';
import { isInFullScreenCall } from '../selectors/calling';
import { isSignalConversation } from '../../util/isSignalConversation';
import { isSignalConversation as getIsSignalConversation } from '../../util/isSignalConversation';
import { renderEmojiPicker } from './renderEmojiPicker';
import { strictAssert } from '../../util/assert';
import { asyncShouldNeverBeCalled } from '../../util/shouldNeverBeCalled';
@ -37,7 +37,18 @@ import { useStoriesActions } from '../ducks/stories';
import { useIsWindowActive } from '../../hooks/useIsWindowActive';
export const SmartStoryViewer = memo(function SmartStoryViewer() {
const storiesActions = useStoriesActions();
const {
reactToStory,
replyToStory,
deleteGroupStoryReply,
deleteGroupStoryReplyForEveryone,
deleteStoryForEveryone,
loadStoryReplies,
markStoryRead,
queueStoryDownload,
setHasAllStoriesUnmuted,
viewStory,
} = useStoriesActions();
const { onUseEmoji } = useEmojisActions();
const {
retryMessageSend,
@ -78,66 +89,87 @@ export const SmartStoryViewer = memo(function SmartStoryViewer() {
selectedStoryData.messageId
);
const handleGoToConversation = useCallback(
(senderId: string) => {
showConversation({ conversationId: senderId });
},
[showConversation]
);
const handleReactToStory = useCallback(
async (emoji, story) => {
const { messageId } = story;
reactToStory(emoji, messageId);
},
[reactToStory]
);
const handleReplyToStory = useCallback(
(message, mentions, timestamp, story) => {
const conversationId = storyInfo?.conversationStory?.conversationId;
strictAssert(conversationId != null, 'conversationId is required');
replyToStory(conversationId, message, mentions, timestamp, story);
},
[storyInfo, replyToStory]
);
const handleTextTooLong = useCallback(() => {
showToast({ toastType: ToastType.MessageBodyTooLong });
}, [showToast]);
if (!storyInfo) {
return null;
}
const { conversationStory, distributionList, storyView } = storyInfo;
const { group, conversationId } = conversationStory;
const isSignalConversation = getIsSignalConversation({
id: conversationId,
});
return (
<StoryViewer
currentIndex={selectedStoryData.currentIndex}
deleteGroupStoryReply={deleteGroupStoryReply}
deleteGroupStoryReplyForEveryone={deleteGroupStoryReplyForEveryone}
deleteStoryForEveryone={deleteStoryForEveryone}
distributionList={distributionList}
getPreferredBadge={getPreferredBadge}
group={conversationStory.group}
group={group}
hasActiveCall={hasActiveCall}
hasAllStoriesUnmuted={hasAllStoriesUnmuted}
hasViewReceiptSetting={hasViewReceiptSetting}
i18n={i18n}
platform={platform}
isInternalUser={internalUser}
isFormattingEnabled={isFormattingEnabled}
isSignalConversation={isSignalConversation({
id: conversationStory.conversationId,
})}
isInternalUser={internalUser}
isSignalConversation={isSignalConversation}
isWindowActive={isWindowActive}
loadStoryReplies={loadStoryReplies}
markStoryRead={markStoryRead}
numStories={selectedStoryData.numStories}
onGoToConversation={handleGoToConversation}
onHideStory={toggleHideStories}
onGoToConversation={senderId => {
showConversation({ conversationId: senderId });
}}
onReactToStory={async (emoji, story) => {
const { messageId } = story;
storiesActions.reactToStory(emoji, messageId);
}}
onReplyToStory={(message, mentions, timestamp, story) => {
storiesActions.replyToStory(
conversationStory.conversationId,
message,
mentions,
timestamp,
story
);
}}
onSetSkinTone={onSetSkinTone}
onTextTooLong={() => {
showToast({ toastType: ToastType.MessageBodyTooLong });
}}
onUseEmoji={onUseEmoji}
onMediaPlaybackStart={pauseVoiceNotePlayer}
onReactToStory={handleReactToStory}
onReplyToStory={handleReplyToStory}
onSetSkinTone={onSetSkinTone}
onTextTooLong={handleTextTooLong}
onUseEmoji={onUseEmoji}
platform={platform}
preferredReactionEmoji={preferredReactionEmoji}
queueStoryDownload={queueStoryDownload}
recentEmojis={recentEmojis}
renderEmojiPicker={renderEmojiPicker}
replyState={replyState}
retryMessageSend={retryMessageSend}
saveAttachment={internalUser ? saveAttachment : asyncShouldNeverBeCalled}
setHasAllStoriesUnmuted={setHasAllStoriesUnmuted}
showContactModal={showContactModal}
showToast={showToast}
skinTone={skinTone}
story={storyView}
storyViewMode={selectedStoryData.storyViewMode}
viewStory={viewStory}
viewTarget={selectedStoryData.viewTarget}
{...storiesActions}
/>
);
});

View file

@ -32,6 +32,10 @@ export type SmartPropsType = Readonly<{
containerWidthBreakpoint: WidthBreakpoint;
}>;
function handleShowDebugLog() {
window.IPC.showDebugLog();
}
export const SmartToastManager = memo(function SmartToastManager({
disableMegaphone = false,
containerWidthBreakpoint,
@ -85,7 +89,7 @@ export const SmartToastManager = memo(function SmartToastManager({
OS={OS.getName()}
toast={toast}
megaphone={disableMegaphone ? undefined : megaphone}
onShowDebugLog={() => window.IPC.showDebugLog()}
onShowDebugLog={handleShowDebugLog}
onUndoArchive={onUndoArchive}
openFileInFolder={openFileInFolder}
hideToast={hideToast}