Always use static/cached selectors in useSelector
This commit is contained in:
parent
d85a1d5074
commit
1e275a917c
13 changed files with 105 additions and 70 deletions
|
@ -10,3 +10,5 @@ export const getHasInitialLoadCompleted = createSelector(
|
||||||
getApp,
|
getApp,
|
||||||
({ hasInitialLoadCompleted }) => hasInitialLoadCompleted
|
({ hasInitialLoadCompleted }) => hasInitialLoadCompleted
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const getAppView = createSelector(getApp, ({ appView }) => appView);
|
||||||
|
|
|
@ -208,6 +208,12 @@ export const getTargetedMessage = createSelector(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
export const getTargetedMessageSource = createSelector(
|
||||||
|
getConversations,
|
||||||
|
(state: ConversationsStateType): string | undefined => {
|
||||||
|
return state.targetedMessageSource;
|
||||||
|
}
|
||||||
|
);
|
||||||
export const getSelectedMessageIds = createSelector(
|
export const getSelectedMessageIds = createSelector(
|
||||||
getConversations,
|
getConversations,
|
||||||
(state: ConversationsStateType): ReadonlyArray<string> | undefined => {
|
(state: ConversationsStateType): ReadonlyArray<string> | undefined => {
|
||||||
|
|
17
ts/state/selectors/inbox.ts
Normal file
17
ts/state/selectors/inbox.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2024 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import type { StateType } from '../reducer';
|
||||||
|
|
||||||
|
const getInboxState = (state: StateType) => state.inbox;
|
||||||
|
|
||||||
|
export const getInboxEnvelopeTimestamp = createSelector(
|
||||||
|
getInboxState,
|
||||||
|
({ envelopeTimestamp }) => envelopeTimestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getInboxFirstEnvelopeTimestamp = createSelector(
|
||||||
|
getInboxState,
|
||||||
|
({ firstEnvelopeTimestamp }) => firstEnvelopeTimestamp
|
||||||
|
);
|
|
@ -25,3 +25,12 @@ export const getContactSafetyNumber = createSelector(
|
||||||
contactID: string
|
contactID: string
|
||||||
): SafetyNumberContactType | void => contacts[contactID]
|
): SafetyNumberContactType | void => contacts[contactID]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const getContactSafetyNumberSelector = createSelector(
|
||||||
|
[getSafetyNumber],
|
||||||
|
({ contacts }) => {
|
||||||
|
return (contactId: string) => {
|
||||||
|
return contacts[contactId];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
@ -16,20 +16,20 @@ import {
|
||||||
getIsMainWindowFullScreen,
|
getIsMainWindowFullScreen,
|
||||||
} from '../selectors/user';
|
} from '../selectors/user';
|
||||||
import { hasSelectedStoryData } from '../selectors/stories';
|
import { hasSelectedStoryData } from '../selectors/stories';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import { useAppActions } from '../ducks/app';
|
import { useAppActions } from '../ducks/app';
|
||||||
import { useConversationsActions } from '../ducks/conversations';
|
import { useConversationsActions } from '../ducks/conversations';
|
||||||
import { useStoriesActions } from '../ducks/stories';
|
import { useStoriesActions } from '../ducks/stories';
|
||||||
import { ErrorBoundary } from '../../components/ErrorBoundary';
|
import { ErrorBoundary } from '../../components/ErrorBoundary';
|
||||||
import { ModalContainer } from '../../components/ModalContainer';
|
import { ModalContainer } from '../../components/ModalContainer';
|
||||||
import { SmartInbox } from './Inbox';
|
import { SmartInbox } from './Inbox';
|
||||||
|
import { getAppView } from '../selectors/app';
|
||||||
|
|
||||||
function renderInbox(): JSX.Element {
|
function renderInbox(): JSX.Element {
|
||||||
return <SmartInbox />;
|
return <SmartInbox />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SmartApp = memo(function SmartApp() {
|
export const SmartApp = memo(function SmartApp() {
|
||||||
const app = useSelector((state: StateType) => state.app);
|
const appView = useSelector(getAppView);
|
||||||
|
|
||||||
const { openInbox } = useAppActions();
|
const { openInbox } = useAppActions();
|
||||||
const { scrollToMessage } = useConversationsActions();
|
const { scrollToMessage } = useConversationsActions();
|
||||||
|
@ -37,7 +37,7 @@ export const SmartApp = memo(function SmartApp() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<App
|
<App
|
||||||
{...app}
|
appView={appView}
|
||||||
isMaximized={useSelector(getIsMainWindowMaximized)}
|
isMaximized={useSelector(getIsMainWindowMaximized)}
|
||||||
isFullScreen={useSelector(getIsMainWindowFullScreen)}
|
isFullScreen={useSelector(getIsMainWindowFullScreen)}
|
||||||
osClassName={OS.getClassName()}
|
osClassName={OS.getClassName()}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import { usePrevious } from '../../hooks/usePrevious';
|
||||||
import { TargetedMessageSource } from '../ducks/conversationsEnums';
|
import { TargetedMessageSource } from '../ducks/conversationsEnums';
|
||||||
import { useConversationsActions } from '../ducks/conversations';
|
import { useConversationsActions } from '../ducks/conversations';
|
||||||
import { useToastActions } from '../ducks/toast';
|
import { useToastActions } from '../ducks/toast';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import { strictAssert } from '../../util/assert';
|
import { strictAssert } from '../../util/assert';
|
||||||
import { ToastType } from '../../types/Toast';
|
import { ToastType } from '../../types/Toast';
|
||||||
import { getNavTabsCollapsed } from '../selectors/items';
|
import { getNavTabsCollapsed } from '../selectors/items';
|
||||||
|
@ -21,6 +20,11 @@ import { useItemsActions } from '../ducks/items';
|
||||||
import { getHasAnyFailedStorySends } from '../selectors/stories';
|
import { getHasAnyFailedStorySends } from '../selectors/stories';
|
||||||
import { getHasPendingUpdate } from '../selectors/updates';
|
import { getHasPendingUpdate } from '../selectors/updates';
|
||||||
import { getOtherTabsUnreadStats } from '../selectors/nav';
|
import { getOtherTabsUnreadStats } from '../selectors/nav';
|
||||||
|
import {
|
||||||
|
getSelectedConversationId,
|
||||||
|
getTargetedMessage,
|
||||||
|
getTargetedMessageSource,
|
||||||
|
} from '../selectors/conversations';
|
||||||
|
|
||||||
function renderConversationView() {
|
function renderConversationView() {
|
||||||
return <SmartConversationView />;
|
return <SmartConversationView />;
|
||||||
|
@ -40,9 +44,9 @@ export const SmartChatsTab = memo(function SmartChatsTab() {
|
||||||
const hasFailedStorySends = useSelector(getHasAnyFailedStorySends);
|
const hasFailedStorySends = useSelector(getHasAnyFailedStorySends);
|
||||||
const hasPendingUpdate = useSelector(getHasPendingUpdate);
|
const hasPendingUpdate = useSelector(getHasPendingUpdate);
|
||||||
const otherTabsUnreadStats = useSelector(getOtherTabsUnreadStats);
|
const otherTabsUnreadStats = useSelector(getOtherTabsUnreadStats);
|
||||||
|
const selectedConversationId = useSelector(getSelectedConversationId);
|
||||||
const { selectedConversationId, targetedMessage, targetedMessageSource } =
|
const targetedMessage = useSelector(getTargetedMessage);
|
||||||
useSelector((state: StateType) => state.conversations);
|
const targetedMessageSource = useSelector(getTargetedMessageSource);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
onConversationClosed,
|
onConversationClosed,
|
||||||
|
@ -60,14 +64,14 @@ export const SmartChatsTab = memo(function SmartChatsTab() {
|
||||||
if (selectedConversationId !== lastOpenedConversationId.current) {
|
if (selectedConversationId !== lastOpenedConversationId.current) {
|
||||||
lastOpenedConversationId.current = selectedConversationId;
|
lastOpenedConversationId.current = selectedConversationId;
|
||||||
if (selectedConversationId) {
|
if (selectedConversationId) {
|
||||||
onConversationOpened(selectedConversationId, targetedMessage);
|
onConversationOpened(selectedConversationId, targetedMessage?.id);
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
selectedConversationId &&
|
selectedConversationId &&
|
||||||
targetedMessage &&
|
targetedMessage &&
|
||||||
targetedMessageSource !== TargetedMessageSource.Focus
|
targetedMessageSource !== TargetedMessageSource.Focus
|
||||||
) {
|
) {
|
||||||
scrollToMessage(selectedConversationId, targetedMessage);
|
scrollToMessage(selectedConversationId, targetedMessage?.id);
|
||||||
}
|
}
|
||||||
}, [onConversationOpened, selectedConversationId, scrollToMessage, targetedMessage, targetedMessageSource]);
|
}, [onConversationOpened, selectedConversationId, scrollToMessage, targetedMessage, targetedMessageSource]);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import { getAddedByForOurPendingInvitation } from '../../util/getAddedByForOurPe
|
||||||
import { imageToBlurHash } from '../../util/imageToBlurHash';
|
import { imageToBlurHash } from '../../util/imageToBlurHash';
|
||||||
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
||||||
import { isSignalConversation } from '../../util/isSignalConversation';
|
import { isSignalConversation } from '../../util/isSignalConversation';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import {
|
import {
|
||||||
getErrorDialogAudioRecorderType,
|
getErrorDialogAudioRecorderType,
|
||||||
getRecordingState,
|
getRecordingState,
|
||||||
|
@ -163,15 +162,23 @@ export const SmartCompositionArea = memo(function SmartCompositionArea({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const quotedMessageProps = useSelector((state: StateType) => {
|
const ourConversationId = useSelector(getUserConversationId);
|
||||||
|
const defaultConversationColor = useSelector(getDefaultConversationColor);
|
||||||
|
|
||||||
|
const quotedMessageProps = useMemo(() => {
|
||||||
return quotedMessage
|
return quotedMessage
|
||||||
? getPropsForQuote(quotedMessage, {
|
? getPropsForQuote(quotedMessage, {
|
||||||
conversationSelector,
|
conversationSelector,
|
||||||
ourConversationId: getUserConversationId(state),
|
ourConversationId,
|
||||||
defaultConversationColor: getDefaultConversationColor(state),
|
defaultConversationColor,
|
||||||
})
|
})
|
||||||
: undefined;
|
: undefined;
|
||||||
});
|
}, [
|
||||||
|
quotedMessage,
|
||||||
|
conversationSelector,
|
||||||
|
ourConversationId,
|
||||||
|
defaultConversationColor,
|
||||||
|
]);
|
||||||
|
|
||||||
const { putItem, removeItem } = useItemsActions();
|
const { putItem, removeItem } = useItemsActions();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import React, { memo, useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import type { ConversationType } from '../ducks/conversations';
|
import type { ConversationType } from '../ducks/conversations';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import {
|
import {
|
||||||
ConversationHeader,
|
ConversationHeader,
|
||||||
OutgoingCallButtonStyle,
|
OutgoingCallButtonStyle,
|
||||||
|
@ -19,14 +18,13 @@ import {
|
||||||
isMissingRequiredProfileSharing,
|
isMissingRequiredProfileSharing,
|
||||||
} from '../selectors/conversations';
|
} from '../selectors/conversations';
|
||||||
import { CallMode } from '../../types/Calling';
|
import { CallMode } from '../../types/Calling';
|
||||||
import { getActiveCall, useCallingActions } from '../ducks/calling';
|
import { useCallingActions } from '../ducks/calling';
|
||||||
import { isAnybodyElseInGroupCall } from '../ducks/callingHelpers';
|
import { isAnybodyElseInGroupCall } from '../ducks/callingHelpers';
|
||||||
import {
|
import {
|
||||||
getConversationCallMode,
|
getConversationCallMode,
|
||||||
useConversationsActions,
|
useConversationsActions,
|
||||||
} from '../ducks/conversations';
|
} from '../ducks/conversations';
|
||||||
import { getHasStoriesSelector } from '../selectors/stories2';
|
import { getHasStoriesSelector } from '../selectors/stories2';
|
||||||
import { getOwn } from '../../util/getOwn';
|
|
||||||
import { getUserACI, getIntl, getTheme } from '../selectors/user';
|
import { getUserACI, getIntl, getTheme } from '../selectors/user';
|
||||||
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
|
@ -39,20 +37,21 @@ import { getGroupMemberships } from '../../util/getGroupMemberships';
|
||||||
import { isGroupOrAdhocCallState } from '../../util/isGroupOrAdhocCall';
|
import { isGroupOrAdhocCallState } from '../../util/isGroupOrAdhocCall';
|
||||||
import { useContactNameData } from '../../components/conversation/ContactName';
|
import { useContactNameData } from '../../components/conversation/ContactName';
|
||||||
import { getAddedByForOurPendingInvitation } from '../../util/getAddedByForOurPendingInvitation';
|
import { getAddedByForOurPendingInvitation } from '../../util/getAddedByForOurPendingInvitation';
|
||||||
|
import { getActiveCallState, getCallSelector } from '../selectors/calling';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOutgoingCallButtonStyle = (
|
const useOutgoingCallButtonStyle = (
|
||||||
conversation: ConversationType,
|
conversation: ConversationType
|
||||||
state: StateType
|
|
||||||
): OutgoingCallButtonStyle => {
|
): OutgoingCallButtonStyle => {
|
||||||
const { calling } = state;
|
const ourAci = useSelector(getUserACI);
|
||||||
const ourAci = getUserACI(state);
|
const activeCall = useSelector(getActiveCallState);
|
||||||
strictAssert(ourAci, 'getOutgoingCallButtonStyle missing our uuid');
|
const callSelector = useSelector(getCallSelector);
|
||||||
|
strictAssert(ourAci, 'useOutgoingCallButtonStyle missing our uuid');
|
||||||
|
|
||||||
if (getActiveCall(calling)) {
|
if (activeCall != null) {
|
||||||
return OutgoingCallButtonStyle.None;
|
return OutgoingCallButtonStyle.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ const getOutgoingCallButtonStyle = (
|
||||||
return OutgoingCallButtonStyle.Both;
|
return OutgoingCallButtonStyle.Both;
|
||||||
case CallMode.Group:
|
case CallMode.Group:
|
||||||
case CallMode.Adhoc: {
|
case CallMode.Adhoc: {
|
||||||
const call = getOwn(calling.callsByConversation, conversation.id);
|
const call = callSelector(conversation.id);
|
||||||
if (
|
if (
|
||||||
isGroupOrAdhocCallState(call) &&
|
isGroupOrAdhocCallState(call) &&
|
||||||
isAnybodyElseInGroupCall(call.peekInfo, ourAci)
|
isAnybodyElseInGroupCall(call.peekInfo, ourAci)
|
||||||
|
@ -94,9 +93,7 @@ export const SmartConversationHeader = memo(function SmartConversationHeader({
|
||||||
const badge = badgeSelector(conversation.badges);
|
const badge = badgeSelector(conversation.badges);
|
||||||
const i18n = useSelector(getIntl);
|
const i18n = useSelector(getIntl);
|
||||||
const hasPanelShowing = useSelector(getHasPanelOpen);
|
const hasPanelShowing = useSelector(getHasPanelOpen);
|
||||||
const outgoingCallButtonStyle = useSelector((state: StateType) => {
|
const outgoingCallButtonStyle = useOutgoingCallButtonStyle(conversation);
|
||||||
return getOutgoingCallButtonStyle(conversation, state);
|
|
||||||
});
|
|
||||||
const theme = useSelector(getTheme);
|
const theme = useSelector(getTheme);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
import React, { memo, useCallback } from 'react';
|
import React, { memo, useCallback } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import { ConversationPanel } from './ConversationPanel';
|
import { ConversationPanel } from './ConversationPanel';
|
||||||
import { ConversationView } from '../../components/conversation/ConversationView';
|
import { ConversationView } from '../../components/conversation/ConversationView';
|
||||||
import { SmartCompositionArea } from './CompositionArea';
|
import { SmartCompositionArea } from './CompositionArea';
|
||||||
|
@ -17,6 +16,7 @@ import {
|
||||||
} from '../selectors/conversations';
|
} from '../selectors/conversations';
|
||||||
import { useComposerActions } from '../ducks/composer';
|
import { useComposerActions } from '../ducks/composer';
|
||||||
import { useConversationsActions } from '../ducks/conversations';
|
import { useConversationsActions } from '../ducks/conversations';
|
||||||
|
import { isShowingAnyModal } from '../selectors/globalModals';
|
||||||
|
|
||||||
function renderCompositionArea(conversationId: string) {
|
function renderCompositionArea(conversationId: string) {
|
||||||
return <SmartCompositionArea id={conversationId} />;
|
return <SmartCompositionArea id={conversationId} />;
|
||||||
|
@ -48,19 +48,10 @@ export const SmartConversationView = memo(
|
||||||
|
|
||||||
const { processAttachments } = useComposerActions();
|
const { processAttachments } = useComposerActions();
|
||||||
|
|
||||||
const hasOpenModal = useSelector((state: StateType) => {
|
const hasOpenModal = useSelector(isShowingAnyModal);
|
||||||
return (
|
const activePanel = useSelector(getActivePanel);
|
||||||
state.globalModals.forwardMessagesProps != null ||
|
const isPanelAnimating = useSelector(getIsPanelAnimating);
|
||||||
state.globalModals.deleteMessagesProps != null ||
|
const shouldHideConversationView = activePanel && !isPanelAnimating;
|
||||||
state.globalModals.hasConfirmationModal
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const shouldHideConversationView = useSelector((state: StateType) => {
|
|
||||||
const activePanel = getActivePanel(state);
|
|
||||||
const isAnimating = getIsPanelAnimating(state);
|
|
||||||
return activePanel && !isAnimating;
|
|
||||||
});
|
|
||||||
|
|
||||||
const onExitSelectMode = useCallback(() => {
|
const onExitSelectMode = useCallback(() => {
|
||||||
toggleSelectMode(false);
|
toggleSelectMode(false);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2023 Signal Messenger, LLC
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { memo } from 'react';
|
import React, { memo, useCallback } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import type { StateType } from '../reducer';
|
import type { StateType } from '../reducer';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
|
@ -25,13 +25,17 @@ export const SmartDeleteMessagesModal = memo(
|
||||||
'Cannot render delete messages modal without messages'
|
'Cannot render delete messages modal without messages'
|
||||||
);
|
);
|
||||||
const { conversationId, messageIds, onDelete } = deleteMessagesProps;
|
const { conversationId, messageIds, onDelete } = deleteMessagesProps;
|
||||||
const isMe = useSelector((state: StateType) => {
|
const conversationSelector = useSelector(getConversationSelector);
|
||||||
return getConversationSelector(state)(conversationId).isMe;
|
const conversation = conversationSelector(conversationId);
|
||||||
});
|
const { isMe } = conversation;
|
||||||
|
|
||||||
const canDeleteForEveryone = useSelector((state: StateType) => {
|
const getCanDeleteForEveryone = useCallback(
|
||||||
return canDeleteMessagesForEveryone(state, { messageIds, isMe });
|
(state: StateType) => {
|
||||||
});
|
return canDeleteMessagesForEveryone(state, { messageIds, isMe });
|
||||||
|
},
|
||||||
|
[messageIds, isMe]
|
||||||
|
);
|
||||||
|
const canDeleteForEveryone = useSelector(getCanDeleteForEveryone);
|
||||||
const lastSelectedMessage = useSelector(getLastSelectedMessage);
|
const lastSelectedMessage = useSelector(getLastSelectedMessage);
|
||||||
const i18n = useSelector(getIntl);
|
const i18n = useSelector(getIntl);
|
||||||
const { toggleDeleteMessagesModal } = useGlobalModalActions();
|
const { toggleDeleteMessagesModal } = useGlobalModalActions();
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import { Inbox } from '../../components/Inbox';
|
import { Inbox } from '../../components/Inbox';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
import { SmartCustomizingPreferredReactionsModal } from './CustomizingPreferredReactionsModal';
|
import { SmartCustomizingPreferredReactionsModal } from './CustomizingPreferredReactionsModal';
|
||||||
|
@ -15,6 +14,11 @@ import { SmartCallsTab } from './CallsTab';
|
||||||
import { useItemsActions } from '../ducks/items';
|
import { useItemsActions } from '../ducks/items';
|
||||||
import { getNavTabsCollapsed } from '../selectors/items';
|
import { getNavTabsCollapsed } from '../selectors/items';
|
||||||
import { SmartChatsTab } from './ChatsTab';
|
import { SmartChatsTab } from './ChatsTab';
|
||||||
|
import { getHasInitialLoadCompleted } from '../selectors/app';
|
||||||
|
import {
|
||||||
|
getInboxEnvelopeTimestamp,
|
||||||
|
getInboxFirstEnvelopeTimestamp,
|
||||||
|
} from '../selectors/inbox';
|
||||||
|
|
||||||
function renderChatsTab() {
|
function renderChatsTab() {
|
||||||
return <SmartChatsTab />;
|
return <SmartChatsTab />;
|
||||||
|
@ -41,17 +45,11 @@ export const SmartInbox = memo(function SmartInbox(): JSX.Element {
|
||||||
const isCustomizingPreferredReactions = useSelector(
|
const isCustomizingPreferredReactions = useSelector(
|
||||||
getIsCustomizingPreferredReactions
|
getIsCustomizingPreferredReactions
|
||||||
);
|
);
|
||||||
const envelopeTimestamp = useSelector(
|
const envelopeTimestamp = useSelector(getInboxEnvelopeTimestamp);
|
||||||
(state: StateType) => state.inbox.envelopeTimestamp
|
const firstEnvelopeTimestamp = useSelector(getInboxFirstEnvelopeTimestamp);
|
||||||
);
|
const hasInitialLoadCompleted = useSelector(getHasInitialLoadCompleted);
|
||||||
const firstEnvelopeTimestamp = useSelector(
|
|
||||||
(state: StateType) => state.inbox.firstEnvelopeTimestamp
|
|
||||||
);
|
|
||||||
const { hasInitialLoadCompleted } = useSelector(
|
|
||||||
(state: StateType) => state.app
|
|
||||||
);
|
|
||||||
|
|
||||||
const navTabsCollapsed = useSelector(getNavTabsCollapsed);
|
const navTabsCollapsed = useSelector(getNavTabsCollapsed);
|
||||||
|
|
||||||
const { toggleNavTabsCollapse } = useItemsActions();
|
const { toggleNavTabsCollapse } = useItemsActions();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { SafetyNumberModal } from '../../components/SafetyNumberModal';
|
import { SafetyNumberModal } from '../../components/SafetyNumberModal';
|
||||||
import type { StateType } from '../reducer';
|
import { getContactSafetyNumberSelector } from '../selectors/safetyNumber';
|
||||||
import { getContactSafetyNumber } from '../selectors/safetyNumber';
|
|
||||||
import { getConversationSelector } from '../selectors/conversations';
|
import { getConversationSelector } from '../selectors/conversations';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
import { useSafetyNumberActions } from '../ducks/safetyNumber';
|
import { useSafetyNumberActions } from '../ducks/safetyNumber';
|
||||||
|
@ -20,9 +19,10 @@ export const SmartSafetyNumberModal = memo(function SmartSafetyNumberModal({
|
||||||
const i18n = useSelector(getIntl);
|
const i18n = useSelector(getIntl);
|
||||||
const conversationSelector = useSelector(getConversationSelector);
|
const conversationSelector = useSelector(getConversationSelector);
|
||||||
const contact = conversationSelector(contactID);
|
const contact = conversationSelector(contactID);
|
||||||
const contactSafetyNumber = useSelector((state: StateType) => {
|
const contactSafetyNumberSelector = useSelector(
|
||||||
return getContactSafetyNumber(state, { contactID });
|
getContactSafetyNumberSelector
|
||||||
});
|
);
|
||||||
|
const contactSafetyNumber = contactSafetyNumberSelector(contactID);
|
||||||
const { generateSafetyNumber, toggleVerified } = useSafetyNumberActions();
|
const { generateSafetyNumber, toggleVerified } = useSafetyNumberActions();
|
||||||
const { toggleSafetyNumberModal } = useGlobalModalActions();
|
const { toggleSafetyNumberModal } = useGlobalModalActions();
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { SafetyNumberViewer } from '../../components/SafetyNumberViewer';
|
import { SafetyNumberViewer } from '../../components/SafetyNumberViewer';
|
||||||
import type { StateType } from '../reducer';
|
|
||||||
import type { SafetyNumberProps } from '../../components/SafetyNumberChangeDialog';
|
import type { SafetyNumberProps } from '../../components/SafetyNumberChangeDialog';
|
||||||
import { getContactSafetyNumber } from '../selectors/safetyNumber';
|
import { getContactSafetyNumberSelector } from '../selectors/safetyNumber';
|
||||||
import { getConversationSelector } from '../selectors/conversations';
|
import { getConversationSelector } from '../selectors/conversations';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
import { useSafetyNumberActions } from '../ducks/safetyNumber';
|
import { useSafetyNumberActions } from '../ducks/safetyNumber';
|
||||||
|
@ -16,9 +15,10 @@ export const SmartSafetyNumberViewer = memo(function SmartSafetyNumberViewer({
|
||||||
onClose,
|
onClose,
|
||||||
}: SafetyNumberProps) {
|
}: SafetyNumberProps) {
|
||||||
const i18n = useSelector(getIntl);
|
const i18n = useSelector(getIntl);
|
||||||
const safetyNumberContact = useSelector((state: StateType) => {
|
const contactSafetyNumberSelector = useSelector(
|
||||||
return getContactSafetyNumber(state, { contactID });
|
getContactSafetyNumberSelector
|
||||||
});
|
);
|
||||||
|
const safetyNumberContact = contactSafetyNumberSelector(contactID);
|
||||||
const conversationSelector = useSelector(getConversationSelector);
|
const conversationSelector = useSelector(getConversationSelector);
|
||||||
const contact = conversationSelector(contactID);
|
const contact = conversationSelector(contactID);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue