Merge pull request #3021 from Bilb/fix-right-panel-close-msg-deleted

fix: close messageInfo when message not in redux store
pull/3022/head
Audric Ackermann 1 year ago committed by GitHub
commit 70311d27da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -2,7 +2,7 @@
"name": "session-desktop", "name": "session-desktop",
"productName": "Session", "productName": "Session",
"description": "Private messaging from your desktop", "description": "Private messaging from your desktop",
"version": "1.11.6", "version": "1.11.7",
"license": "GPL-3.0", "license": "GPL-3.0",
"author": { "author": {
"name": "Oxen Labs", "name": "Oxen Labs",

@ -76,7 +76,6 @@ interface Props {
selectedConversation?: ReduxConversationType; selectedConversation?: ReduxConversationType;
messagesProps: Array<SortedMessageModelProps>; messagesProps: Array<SortedMessageModelProps>;
selectedMessages: Array<string>; selectedMessages: Array<string>;
showMessageDetails: boolean;
isRightPanelShowing: boolean; isRightPanelShowing: boolean;
hasOngoingCallWithFocusedConvo: boolean; hasOngoingCallWithFocusedConvo: boolean;
htmlDirection: HTMLDirection; htmlDirection: HTMLDirection;

@ -22,7 +22,7 @@ import { MessageRenderingProps } from '../../../../models/messageType';
import { pushUnblockToSend } from '../../../../session/utils/Toast'; import { pushUnblockToSend } from '../../../../session/utils/Toast';
import { import {
openRightPanel, openRightPanel,
showMessageDetailsView, showMessageInfoView,
toggleSelectedMessageId, toggleSelectedMessageId,
} from '../../../../state/ducks/conversations'; } from '../../../../state/ducks/conversations';
import { setRightOverlayMode } from '../../../../state/ducks/section'; import { setRightOverlayMode } from '../../../../state/ducks/section';
@ -173,8 +173,7 @@ export const showMessageInfoOverlay = async ({
}) => { }) => {
const found = await Data.getMessageById(messageId); const found = await Data.getMessageById(messageId);
if (found) { if (found) {
const messageDetailsProps = await found.getPropsForMessageDetail(); dispatch(showMessageInfoView(messageId));
dispatch(showMessageDetailsView(messageDetailsProps));
dispatch( dispatch(
setRightOverlayMode({ setRightOverlayMode({
type: 'message_info', type: 'message_info',

@ -1,10 +1,9 @@
import React, { ReactElement, useRef, useState } from 'react'; import React, { ReactElement, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { useMouse } from 'react-use'; import { useMouse } from 'react-use';
import styled from 'styled-components'; import styled from 'styled-components';
import { useRightOverlayMode } from '../../../../hooks/useUI';
import { isUsAnySogsFromCache } from '../../../../session/apis/open_group_api/sogsv3/knownBlindedkeys'; import { isUsAnySogsFromCache } from '../../../../session/apis/open_group_api/sogsv3/knownBlindedkeys';
import { UserUtils } from '../../../../session/utils'; import { UserUtils } from '../../../../session/utils';
import { getRightOverlayMode } from '../../../../state/selectors/section';
import { useIsMessageSelectionMode } from '../../../../state/selectors/selectedConversation'; import { useIsMessageSelectionMode } from '../../../../state/selectors/selectedConversation';
import { THEME_GLOBALS } from '../../../../themes/globals'; import { THEME_GLOBALS } from '../../../../themes/globals';
import { SortedReactionList } from '../../../../types/Reaction'; import { SortedReactionList } from '../../../../types/Reaction';
@ -79,7 +78,7 @@ export const Reaction = (props: ReactionProps): ReactElement => {
handlePopupClick, handlePopupClick,
} = props; } = props;
const rightOverlayMode = useSelector(getRightOverlayMode); const rightOverlayMode = useRightOverlayMode();
const isMessageSelection = useIsMessageSelectionMode(); const isMessageSelection = useIsMessageSelectionMode();
const reactionsMap = (reactions && Object.fromEntries(reactions)) || {}; const reactionsMap = (reactions && Object.fromEntries(reactions)) || {};
const senders = reactionsMap[emoji]?.senders || []; const senders = reactionsMap[emoji]?.senders || [];

@ -1,27 +1,40 @@
import React from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components'; import styled from 'styled-components';
// tslint:disable-next-line: no-submodule-imports // tslint:disable-next-line: no-submodule-imports
import useKey from 'react-use/lib/useKey'; import useKey from 'react-use/lib/useKey';
import { closeMessageDetailsView, closeRightPanel } from '../../../../../state/ducks/conversations'; import { PropsForAttachment, closeRightPanel } from '../../../../../state/ducks/conversations';
import { resetRightOverlayMode, setRightOverlayMode } from '../../../../../state/ducks/section'; import { resetRightOverlayMode, setRightOverlayMode } from '../../../../../state/ducks/section';
import { getMessageDetailsViewProps } from '../../../../../state/selectors/conversations'; import { getMessageInfoId } from '../../../../../state/selectors/conversations';
import { Flex } from '../../../../basic/Flex'; import { Flex } from '../../../../basic/Flex';
import { Header, HeaderTitle, StyledScrollContainer } from '../components'; import { Header, HeaderTitle, StyledScrollContainer } from '../components';
import { Data } from '../../../../../data/data';
import { useRightOverlayMode } from '../../../../../hooks/useUI';
import { import {
replyToMessage, replyToMessage,
resendMessage, resendMessage,
} from '../../../../../interactions/conversationInteractions'; } from '../../../../../interactions/conversationInteractions';
import { deleteMessagesById } from '../../../../../interactions/conversations/unsendingInteractions'; import { deleteMessagesById } from '../../../../../interactions/conversations/unsendingInteractions';
import { import {
useMessageAttachments,
useMessageDirection,
useMessageIsDeletable, useMessageIsDeletable,
useMessageQuote, useMessageQuote,
useMessageSender,
useMessageServerTimestamp,
useMessageText, useMessageText,
useMessageTimestamp,
} from '../../../../../state/selectors'; } from '../../../../../state/selectors';
import { getRightOverlayMode } from '../../../../../state/selectors/section'; import { useSelectedConversationKey } from '../../../../../state/selectors/selectedConversation';
import { canDisplayImage } from '../../../../../types/Attachment'; import { canDisplayImage } from '../../../../../types/Attachment';
import { isAudio } from '../../../../../types/MIME';
import {
getAudioDuration,
getVideoDuration,
} from '../../../../../types/attachments/VisualAttachment';
import { GoogleChrome } from '../../../../../util';
import { saveAttachmentToDisk } from '../../../../../util/attachmentsUtil'; import { saveAttachmentToDisk } from '../../../../../util/attachmentsUtil';
import { SpacerLG, SpacerMD, SpacerXL } from '../../../../basic/Text'; import { SpacerLG, SpacerMD, SpacerXL } from '../../../../basic/Text';
import { PanelButtonGroup, PanelIconButton } from '../../../../buttons'; import { PanelButtonGroup, PanelIconButton } from '../../../../buttons';
@ -78,36 +91,134 @@ const StyledMessageDetail = styled.div`
padding: var(--margins-sm) var(--margins-2xl) var(--margins-lg); padding: var(--margins-sm) var(--margins-2xl) var(--margins-lg);
`; `;
export const OverlayMessageInfo = () => { type MessageInfoProps = {
const rightOverlayMode = useSelector(getRightOverlayMode); errors: Array<Error>;
const messageDetailProps = useSelector(getMessageDetailsViewProps); attachments: Array<PropsForAttachment>;
const isDeletable = useMessageIsDeletable(messageDetailProps?.messageId); };
async function getPropsForMessageInfo(
messageId: string | undefined,
attachments: Array<PropsForAttachment>
): Promise<MessageInfoProps | null> {
if (!messageId) {
return null;
}
const found = await Data.getMessageById(messageId);
const attachmentsWithMediaDetails: Array<PropsForAttachment> = [];
if (found) {
// process attachments so we have the fileSize, url and screenshots
for (let i = 0; i < attachments.length; i++) {
const props = found.getPropsForAttachment(attachments[i]);
if (
props?.contentType &&
GoogleChrome.isVideoTypeSupported(props?.contentType) &&
!props.duration &&
props.url
) {
// eslint-disable-next-line no-await-in-loop
const duration = await getVideoDuration({
objectUrl: props.url,
contentType: props.contentType,
});
attachmentsWithMediaDetails.push({
...props,
duration,
});
} else if (props?.contentType && isAudio(props.contentType) && !props.duration && props.url) {
// eslint-disable-next-line no-await-in-loop
const duration = await getAudioDuration({
objectUrl: props.url,
contentType: props.contentType,
});
attachmentsWithMediaDetails.push({
...props,
duration,
});
} else if (props) {
attachmentsWithMediaDetails.push(props);
}
}
// This will make the error message for outgoing key errors a bit nicer
const errors = (found.get('errors') || []).map((error: any) => {
return error;
});
const toRet: MessageInfoProps = {
errors,
attachments: attachmentsWithMediaDetails,
};
return toRet;
}
return null;
}
function useMessageInfo(messageId: string | undefined) {
const [details, setDetails] = useState<MessageInfoProps | null>(null);
const fromState = useMessageAttachments(messageId);
// this is not ideal, but also doesn't seem to create any performance issue at the moment.
// TODO: ideally, we'd want to save the attachment duration anytime we save one to the disk (incoming/outgoing), and just retrieve it from the redux state here.
useEffect(() => {
let mounted = true;
// eslint-disable-next-line more/no-then
void getPropsForMessageInfo(messageId, fromState || [])
.then(result => {
if (mounted) {
setDetails(result);
}
})
.catch(window.log.error);
return () => {
mounted = false;
};
}, [fromState, messageId]);
return details;
}
export const OverlayMessageInfo = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
useKey('Escape', () => { const rightOverlayMode = useRightOverlayMode();
const messageId = useSelector(getMessageInfoId);
const messageInfo = useMessageInfo(messageId);
const isDeletable = useMessageIsDeletable(messageId);
const direction = useMessageDirection(messageId);
const timestamp = useMessageTimestamp(messageId);
const serverTimestamp = useMessageServerTimestamp(messageId);
const sender = useMessageSender(messageId);
// we close the right panel when switching conversation so the convoId of that message is always the selectedConversationKey
// is always the currently selected conversation
const convoId = useSelectedConversationKey();
const closePanel = useCallback(() => {
dispatch(closeRightPanel()); dispatch(closeRightPanel());
dispatch(resetRightOverlayMode()); dispatch(resetRightOverlayMode());
dispatch(closeMessageDetailsView()); }, [dispatch]);
});
useKey('Escape', closePanel);
// close the panel if the messageInfo is associated with a deleted message
useEffect(() => {
if (!sender) {
closePanel();
}
}, [sender, closePanel]);
if (!rightOverlayMode || !messageDetailProps) { if (!rightOverlayMode || !messageInfo || !convoId || !messageId || !sender) {
return null; return null;
} }
const { params } = rightOverlayMode; const { params } = rightOverlayMode;
const visibleAttachmentIndex = params?.visibleAttachmentIndex || 0; const visibleAttachmentIndex = params?.visibleAttachmentIndex || 0;
const { const { errors, attachments } = messageInfo;
convoId,
messageId,
sender,
attachments,
timestamp,
serverTimestamp,
errors,
direction,
} = messageDetailProps;
const hasAttachments = attachments && attachments.length > 0; const hasAttachments = attachments && attachments.length > 0;
const supportsAttachmentCarousel = canDisplayImage(attachments); const supportsAttachmentCarousel = canDisplayImage(attachments);
@ -140,14 +251,7 @@ export const OverlayMessageInfo = () => {
return ( return (
<StyledScrollContainer> <StyledScrollContainer>
<Flex container={true} flexDirection={'column'} alignItems={'center'}> <Flex container={true} flexDirection={'column'} alignItems={'center'}>
<Header <Header hideBackButton={true} closeButtonOnClick={closePanel}>
hideBackButton={true}
closeButtonOnClick={() => {
dispatch(closeRightPanel());
dispatch(resetRightOverlayMode());
dispatch(closeMessageDetailsView());
}}
>
<HeaderTitle>{window.i18n('messageInfo')}</HeaderTitle> <HeaderTitle>{window.i18n('messageInfo')}</HeaderTitle>
</Header> </Header>
<StyledMessageDetailContainer> <StyledMessageDetailContainer>
@ -178,7 +282,7 @@ export const OverlayMessageInfo = () => {
<SpacerMD /> <SpacerMD />
</> </>
)} )}
<MessageInfo /> <MessageInfo messageId={messageId} errors={messageInfo.errors} />
<SpacerLG /> <SpacerLG />
<PanelButtonGroup style={{ margin: '0' }}> <PanelButtonGroup style={{ margin: '0' }}>
<PanelIconButton <PanelIconButton

@ -2,10 +2,16 @@ import { ipcRenderer } from 'electron';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import moment from 'moment'; import moment from 'moment';
import React from 'react'; import React from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components'; import styled from 'styled-components';
import { MessageFrom } from '.'; import { MessageFrom } from '.';
import { getMessageDetailsViewProps } from '../../../../../../state/selectors/conversations'; import {
useMessageDirection,
useMessageReceivedAt,
useMessageSender,
useMessageServerTimestamp,
useMessageTimestamp,
} from '../../../../../../state/selectors';
import { Flex } from '../../../../../basic/Flex'; import { Flex } from '../../../../../basic/Flex';
import { SpacerSM } from '../../../../../basic/Text'; import { SpacerSM } from '../../../../../basic/Text';
@ -51,16 +57,18 @@ const showDebugLog = () => {
ipcRenderer.send('show-debug-log'); ipcRenderer.send('show-debug-log');
}; };
export const MessageInfo = () => { export const MessageInfo = ({ messageId, errors }: { messageId: string; errors: Array<Error> }) => {
const messageDetailProps = useSelector(getMessageDetailsViewProps); const sender = useMessageSender(messageId);
const direction = useMessageDirection(messageId);
const sentAt = useMessageTimestamp(messageId);
const serverTimestamp = useMessageServerTimestamp(messageId);
const receivedAt = useMessageReceivedAt(messageId);
if (!messageDetailProps) { if (!messageId || !sender) {
return null; return null;
} }
const { errors, receivedAt, sentAt, direction, sender } = messageDetailProps; const sentAtStr = `${moment(serverTimestamp || sentAt).format(formatTimestamps)}`;
const sentAtStr = `${moment(sentAt).format(formatTimestamps)}`;
const receivedAtStr = `${moment(receivedAt).format(formatTimestamps)}`; const receivedAtStr = `${moment(receivedAt).format(formatTimestamps)}`;
const hasError = !isEmpty(errors); const hasError = !isEmpty(errors);

@ -68,7 +68,6 @@ import {
FindAndFormatContactType, FindAndFormatContactType,
LastMessageStatusType, LastMessageStatusType,
MessageModelPropsWithoutConvoProps, MessageModelPropsWithoutConvoProps,
MessagePropsDetails,
PropsForAttachment, PropsForAttachment,
PropsForExpirationTimer, PropsForExpirationTimer,
PropsForExpiringMessage, PropsForExpiringMessage,
@ -84,7 +83,6 @@ import {
messagesChanged, messagesChanged,
} from '../state/ducks/conversations'; } from '../state/ducks/conversations';
import { AttachmentTypeWithPath, isVoiceMessage } from '../types/Attachment'; import { AttachmentTypeWithPath, isVoiceMessage } from '../types/Attachment';
import { isAudio } from '../types/MIME';
import { import {
deleteExternalMessageFiles, deleteExternalMessageFiles,
getAbsoluteAttachmentPath, getAbsoluteAttachmentPath,
@ -93,10 +91,8 @@ import {
loadQuoteData, loadQuoteData,
} from '../types/MessageAttachment'; } from '../types/MessageAttachment';
import { ReactionList } from '../types/Reaction'; import { ReactionList } from '../types/Reaction';
import { getAudioDuration, getVideoDuration } from '../types/attachments/VisualAttachment';
import { getAttachmentMetadata } from '../types/message/initializeAttachmentMetadata'; import { getAttachmentMetadata } from '../types/message/initializeAttachmentMetadata';
import { assertUnreachable, roomHasBlindEnabled } from '../types/sqlSharedTypes'; import { assertUnreachable, roomHasBlindEnabled } from '../types/sqlSharedTypes';
import { GoogleChrome } from '../util';
import { LinkPreviews } from '../util/linkPreviews'; import { LinkPreviews } from '../util/linkPreviews';
import { Notifications } from '../util/notifications'; import { Notifications } from '../util/notifications';
import { Storage } from '../util/storage'; import { Storage } from '../util/storage';
@ -730,62 +726,6 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
}; };
} }
public async getPropsForMessageDetail(): Promise<MessagePropsDetails> {
// process attachments so we have the fileSize, url and screenshots
const attachments = this.get('attachments') || [];
for (let i = 0; i < attachments.length; i++) {
let props = this.getPropsForAttachment(attachments[i]);
if (
props?.contentType &&
GoogleChrome.isVideoTypeSupported(props?.contentType) &&
!props.duration &&
props.url
) {
// eslint-disable-next-line no-await-in-loop
const duration = await getVideoDuration({
objectUrl: props.url,
contentType: props.contentType,
});
props = {
...props,
duration,
};
}
if (props?.contentType && isAudio(props?.contentType) && !props.duration && props.url) {
// eslint-disable-next-line no-await-in-loop
const duration = await getAudioDuration({
objectUrl: props.url,
contentType: props.contentType,
});
props = {
...props,
duration,
};
}
attachments[i] = props;
}
// This will make the error message for outgoing key errors a bit nicer
const errors = (this.get('errors') || []).map((error: any) => {
return error;
});
const toRet: MessagePropsDetails = {
sentAt: this.get('sent_at') || 0,
receivedAt: this.get('received_at') || 0,
convoId: this.get('conversationId'),
messageId: this.get('id'),
errors,
direction: this.get('direction'),
sender: this.get('source'),
attachments,
timestamp: this.get('timestamp'),
serverTimestamp: this.get('serverTimestamp'),
};
return toRet;
}
/** /**
* Uploads attachments, previews and quotes. * Uploads attachments, previews and quotes.
* *

@ -5,6 +5,10 @@ import { ReplyingToMessageProps } from '../../components/conversation/compositio
import { QuotedAttachmentType } from '../../components/conversation/message/message-content/quote/Quote'; import { QuotedAttachmentType } from '../../components/conversation/message/message-content/quote/Quote';
import { LightBoxOptions } from '../../components/conversation/SessionConversation'; import { LightBoxOptions } from '../../components/conversation/SessionConversation';
import { Data } from '../../data/data'; import { Data } from '../../data/data';
import {
ConversationInteractionStatus,
ConversationInteractionType,
} from '../../interactions/conversationInteractions';
import { import {
CONVERSATION_PRIORITIES, CONVERSATION_PRIORITIES,
ConversationNotificationSettingType, ConversationNotificationSettingType,
@ -22,10 +26,6 @@ import {
DisappearingMessageType, DisappearingMessageType,
} from '../../session/disappearing_messages/types'; } from '../../session/disappearing_messages/types';
import { ReactionList } from '../../types/Reaction'; import { ReactionList } from '../../types/Reaction';
import {
ConversationInteractionStatus,
ConversationInteractionType,
} from '../../interactions/conversationInteractions';
export type CallNotificationType = 'missed-call' | 'started-call' | 'answered-a-call'; export type CallNotificationType = 'missed-call' | 'started-call' | 'answered-a-call';
@ -60,19 +60,6 @@ export type ContactPropsMessageDetail = {
errors?: Array<Error>; errors?: Array<Error>;
}; };
export type MessagePropsDetails = {
sentAt: number;
receivedAt: number;
errors: Array<Error>;
sender: string;
convoId: string;
messageId: string;
direction: MessageModelType;
attachments: Array<PropsForAttachment>;
timestamp?: number;
serverTimestamp?: number;
};
export type LastMessageStatusType = 'sending' | 'sent' | 'read' | 'error' | undefined; export type LastMessageStatusType = 'sending' | 'sent' | 'read' | 'error' | undefined;
export type FindAndFormatContactType = { export type FindAndFormatContactType = {
@ -322,7 +309,7 @@ export type ConversationsStateType = {
// NOTE the messages quoted by other messages which are in view // NOTE the messages quoted by other messages which are in view
quotes: QuoteLookupType; quotes: QuoteLookupType;
firstUnreadMessageId: string | undefined; firstUnreadMessageId: string | undefined;
messageDetailProps?: MessagePropsDetails; messageInfoId: string | undefined;
showRightPanel: boolean; showRightPanel: boolean;
selectedMessageIds: Array<string>; selectedMessageIds: Array<string>;
lightBox?: LightBoxOptions; lightBox?: LightBoxOptions;
@ -523,7 +510,7 @@ export function getEmptyConversationState(): ConversationsStateType {
conversationLookup: {}, conversationLookup: {},
messages: [], messages: [],
quotes: {}, quotes: {},
messageDetailProps: undefined, messageInfoId: undefined,
showRightPanel: false, showRightPanel: false,
selectedMessageIds: [], selectedMessageIds: [],
areMoreMessagesBeingFetched: false, // top or bottom areMoreMessagesBeingFetched: false, // top or bottom
@ -677,16 +664,9 @@ const conversationsSlice = createSlice({
name: 'conversations', name: 'conversations',
initialState: getEmptyConversationState(), initialState: getEmptyConversationState(),
reducers: { reducers: {
showMessageDetailsView( showMessageInfoView(state: ConversationsStateType, action: PayloadAction<string>) {
state: ConversationsStateType,
action: PayloadAction<MessagePropsDetails>
) {
// force the right panel to be hidden when showing message detail view // force the right panel to be hidden when showing message detail view
return { ...state, messageDetailProps: action.payload, showRightPanel: false }; return { ...state, messageInfoId: action.payload, showRightPanel: false };
},
closeMessageDetailsView(state: ConversationsStateType) {
return { ...state, messageDetailProps: undefined };
}, },
openRightPanel(state: ConversationsStateType) { openRightPanel(state: ConversationsStateType) {
@ -706,7 +686,7 @@ const conversationsSlice = createSlice({
return state; return state;
}, },
closeRightPanel(state: ConversationsStateType) { closeRightPanel(state: ConversationsStateType) {
return { ...state, showRightPanel: false }; return { ...state, showRightPanel: false, messageInfoId: undefined };
}, },
addMessageIdToSelection(state: ConversationsStateType, action: PayloadAction<string>) { addMessageIdToSelection(state: ConversationsStateType, action: PayloadAction<string>) {
if (state.selectedMessageIds.some(id => id === action.payload)) { if (state.selectedMessageIds.some(id => id === action.payload)) {
@ -887,7 +867,7 @@ const conversationsSlice = createSlice({
selectedMessageIds: [], selectedMessageIds: [],
lightBox: undefined, lightBox: undefined,
messageDetailProps: undefined, messageInfoId: undefined,
quotedMessage: undefined, quotedMessage: undefined,
nextMessageToPlay: undefined, nextMessageToPlay: undefined,
@ -1134,8 +1114,7 @@ export const {
resetOldBottomMessageId, resetOldBottomMessageId,
markConversationFullyRead, markConversationFullyRead,
// layout stuff // layout stuff
showMessageDetailsView, showMessageInfoView,
closeMessageDetailsView,
openRightPanel, openRightPanel,
closeRightPanel, closeRightPanel,
addMessageIdToSelection, addMessageIdToSelection,

@ -9,7 +9,6 @@ import {
MentionsMembersType, MentionsMembersType,
MessageModelPropsWithConvoProps, MessageModelPropsWithConvoProps,
MessageModelPropsWithoutConvoProps, MessageModelPropsWithoutConvoProps,
MessagePropsDetails,
PropsForQuote, PropsForQuote,
QuoteLookupType, QuoteLookupType,
ReduxConversationType, ReduxConversationType,
@ -493,11 +492,7 @@ export const getGlobalUnreadMessageCount = createSelector(
_getGlobalUnreadCount _getGlobalUnreadCount
); );
export const isMessageDetailView = (state: StateType): boolean => export const getMessageInfoId = (state: StateType) => state.conversations.messageInfoId;
state.conversations.messageDetailProps !== undefined;
export const getMessageDetailsViewProps = (state: StateType): MessagePropsDetails | undefined =>
state.conversations.messageDetailProps;
export const isRightPanelShowing = (state: StateType): boolean => export const isRightPanelShowing = (state: StateType): boolean =>
state.conversations.showRightPanel; state.conversations.showRightPanel;

@ -108,7 +108,7 @@ export const useMessageStatus = (
return useMessagePropsByMessageId(messageId)?.propsForMessage.status; return useMessagePropsByMessageId(messageId)?.propsForMessage.status;
}; };
export function useMessageSender(messageId: string) { export function useMessageSender(messageId: string | undefined) {
return useMessagePropsByMessageId(messageId)?.propsForMessage.sender; return useMessagePropsByMessageId(messageId)?.propsForMessage.sender;
} }
@ -116,11 +116,15 @@ export function useMessageIsDeletableForEveryone(messageId: string | undefined)
return useMessagePropsByMessageId(messageId)?.propsForMessage.isDeletableForEveryone; return useMessagePropsByMessageId(messageId)?.propsForMessage.isDeletableForEveryone;
} }
export function useMessageServerTimestamp(messageId: string) { export function useMessageServerTimestamp(messageId: string | undefined) {
return useMessagePropsByMessageId(messageId)?.propsForMessage.serverTimestamp; return useMessagePropsByMessageId(messageId)?.propsForMessage.serverTimestamp;
} }
export function useMessageTimestamp(messageId: string) { export function useMessageReceivedAt(messageId: string | undefined) {
return useMessagePropsByMessageId(messageId)?.propsForMessage.receivedAt;
}
export function useMessageTimestamp(messageId: string | undefined) {
return useMessagePropsByMessageId(messageId)?.propsForMessage.timestamp; return useMessagePropsByMessageId(messageId)?.propsForMessage.timestamp;
} }

@ -1,7 +1,7 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { SessionSettingCategory } from '../../components/settings/SessionSettings'; import { SessionSettingCategory } from '../../components/settings/SessionSettings';
import { LeftOverlayMode, RightOverlayMode, SectionStateType, SectionType } from '../ducks/section'; import { LeftOverlayMode, SectionStateType, SectionType } from '../ducks/section';
import { StateType } from '../reducer'; import { StateType } from '../reducer';
export const getSection = (state: StateType): SectionStateType => state.section; export const getSection = (state: StateType): SectionStateType => state.section;
@ -30,7 +30,7 @@ export const getLeftOverlayMode = createSelector(
(state: SectionStateType): LeftOverlayMode | undefined => state.leftOverlayMode (state: SectionStateType): LeftOverlayMode | undefined => state.leftOverlayMode
); );
export const getRightOverlayMode = (state: StateType): RightOverlayMode | undefined => { export const getRightOverlayMode = (state: StateType) => {
return state.section.rightOverlayMode; return state.section.rightOverlayMode;
}; };

@ -1,5 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { SessionConversation } from '../../components/conversation/SessionConversation'; import { SessionConversation } from '../../components/conversation/SessionConversation';
import { HTMLDirection } from '../../util/i18n';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
import { StateType } from '../reducer'; import { StateType } from '../reducer';
import { getHasOngoingCallWithFocusedConvo } from '../selectors/call'; import { getHasOngoingCallWithFocusedConvo } from '../selectors/call';
@ -9,14 +10,12 @@ import {
getSelectedConversation, getSelectedConversation,
getSelectedMessageIds, getSelectedMessageIds,
getSortedMessagesOfSelectedConversation, getSortedMessagesOfSelectedConversation,
isMessageDetailView,
isRightPanelShowing, isRightPanelShowing,
} from '../selectors/conversations'; } from '../selectors/conversations';
import { getSelectedConversationKey } from '../selectors/selectedConversation'; import { getSelectedConversationKey } from '../selectors/selectedConversation';
import { getStagedAttachmentsForCurrentConversation } from '../selectors/stagedAttachments'; import { getStagedAttachmentsForCurrentConversation } from '../selectors/stagedAttachments';
import { getTheme } from '../selectors/theme'; import { getTheme } from '../selectors/theme';
import { getOurDisplayNameInProfile, getOurNumber } from '../selectors/user'; import { getOurDisplayNameInProfile, getOurNumber } from '../selectors/user';
import { HTMLDirection } from '../../util/i18n';
type SmartSessionConversationOwnProps = { type SmartSessionConversationOwnProps = {
htmlDirection: HTMLDirection; htmlDirection: HTMLDirection;
@ -30,7 +29,6 @@ const mapStateToProps = (state: StateType, ownProps: SmartSessionConversationOwn
messagesProps: getSortedMessagesOfSelectedConversation(state), messagesProps: getSortedMessagesOfSelectedConversation(state),
ourDisplayNameInProfile: getOurDisplayNameInProfile(state), ourDisplayNameInProfile: getOurDisplayNameInProfile(state),
ourNumber: getOurNumber(state), ourNumber: getOurNumber(state),
showMessageDetails: isMessageDetailView(state),
isRightPanelShowing: isRightPanelShowing(state), isRightPanelShowing: isRightPanelShowing(state),
selectedMessages: getSelectedMessageIds(state), selectedMessages: getSelectedMessageIds(state),
lightBoxOptions: getLightBoxOptions(state), lightBoxOptions: getLightBoxOptions(state),

Loading…
Cancel
Save