fix loading of messages props

pull/1783/head
Audric Ackermann 4 years ago
parent 3f0088ed2a
commit f0db797a9a
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -379,9 +379,11 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
multiSelectMode, multiSelectMode,
} = this.props; } = this.props;
if (!quote || !quote.authorPhoneNumber) { if (!quote || !quote.authorPhoneNumber || !quote.messageId) {
return null; return null;
} }
const quoteId = _.toNumber(quote.messageId);
const { authorPhoneNumber, referencedMessageNotFound } = quote;
const withContentAbove = conversationType === 'group' && direction === 'incoming'; const withContentAbove = conversationType === 'group' && direction === 'incoming';
@ -398,8 +400,7 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
this.props.onSelectMessage(id); this.props.onSelectMessage(id);
return; return;
} }
const { authorPhoneNumber, messageId: quoteId, referencedMessageNotFound } = quote; void this.props.onQuoteClick?.({
quote?.onClick({
quoteAuthor: authorPhoneNumber, quoteAuthor: authorPhoneNumber,
quoteId, quoteId,
referencedMessageNotFound, referencedMessageNotFound,
@ -812,7 +813,19 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
{this.renderAttachment()} {this.renderAttachment()}
{this.renderPreview()} {this.renderPreview()}
{this.renderText()} {this.renderText()}
<MessageMetadata {...this.props} isShowingImage={this.isShowingImage()} /> <MessageMetadata
{..._.omit(
this.props,
'onSelectMessage',
'onDeleteMessage',
'onReply',
'onShowDetail',
'onClickAttachment',
'onDownload',
'onQuoteClick'
)}
isShowingImage={this.isShowingImage()}
/>
</div> </div>
{this.renderError(!isIncoming)} {this.renderError(!isIncoming)}
{this.renderContextMenu()} {this.renderContextMenu()}

@ -13,7 +13,7 @@ import { ConversationTypeEnum } from '../../models/conversation';
import { useEncryptedFileFetch } from '../../hooks/useEncryptedFileFetch'; import { useEncryptedFileFetch } from '../../hooks/useEncryptedFileFetch';
interface QuoteProps { export type QuotePropsWithoutListener = {
attachment?: QuotedAttachmentType; attachment?: QuotedAttachmentType;
authorPhoneNumber: string; authorPhoneNumber: string;
authorProfileName?: string; authorProfileName?: string;
@ -24,10 +24,13 @@ interface QuoteProps {
convoId: string; convoId: string;
isPublic?: boolean; isPublic?: boolean;
withContentAbove: boolean; withContentAbove: boolean;
onClick?: (e: any) => void;
text: string; text: string;
referencedMessageNotFound: boolean; referencedMessageNotFound: boolean;
} };
export type QuotePropsWithListener = QuotePropsWithoutListener & {
onClick?: (e: any) => void;
};
export interface QuotedAttachmentType { export interface QuotedAttachmentType {
contentType: MIME.MIMEType; contentType: MIME.MIMEType;
@ -43,7 +46,7 @@ interface Attachment {
objectUrl?: string; objectUrl?: string;
} }
function validateQuote(quote: QuoteProps): boolean { function validateQuote(quote: QuotePropsWithoutListener): boolean {
if (quote.text) { if (quote.text) {
return true; return true;
} }
@ -295,7 +298,7 @@ export const QuoteReferenceWarning = (props: any) => {
); );
}; };
export const Quote = (props: QuoteProps) => { export const Quote = (props: QuotePropsWithListener) => {
const [imageBroken, setImageBroken] = useState(false); const [imageBroken, setImageBroken] = useState(false);
const handleImageErrorBound = null; const handleImageErrorBound = null;

@ -39,11 +39,6 @@ const getCategories = () => {
title: window.i18n('blockedSettingsTitle'), title: window.i18n('blockedSettingsTitle'),
hidden: false, hidden: false,
}, },
{
id: SessionSettingCategory.Permissions,
title: window.i18n('permissionSettingsTitle'),
hidden: true,
},
{ {
id: SessionSettingCategory.Notifications, id: SessionSettingCategory.Notifications,
title: window.i18n('notificationsSettingsTitle'), title: window.i18n('notificationsSettingsTitle'),

@ -27,7 +27,7 @@ export interface SessionConfirmDialogProps {
sessionIcon?: SessionIconType; sessionIcon?: SessionIconType;
iconSize?: SessionIconSize; iconSize?: SessionIconSize;
theme?: DefaultTheme; theme?: DefaultTheme;
shouldShowConfirm?: () => boolean | undefined; shouldShowConfirm?: boolean | undefined;
} }
const SessionConfirmInner = (props: SessionConfirmDialogProps) => { const SessionConfirmInner = (props: SessionConfirmDialogProps) => {
@ -70,7 +70,7 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => {
window.inboxStore?.dispatch(updateConfirmModal(null)); window.inboxStore?.dispatch(updateConfirmModal(null));
}; };
if (shouldShowConfirm && !shouldShowConfirm()) { if (shouldShowConfirm && !shouldShowConfirm) {
return null; return null;
} }

@ -25,7 +25,7 @@ export const SessionToggle = (props: Props) => {
props.onClick(); props.onClick();
}; };
if (props.confirmationDialogParams && props.confirmationDialogParams.shouldShowConfirm()) { if (props.confirmationDialogParams && props.confirmationDialogParams.shouldShowConfirm) {
// If item needs a confirmation dialog to turn ON, render it // If item needs a confirmation dialog to turn ON, render it
const closeConfirmModal = () => { const closeConfirmModal = () => {
dispatch(updateConfirmModal(null)); dispatch(updateConfirmModal(null));

@ -242,7 +242,7 @@ export class SessionCompositionBox extends React.Component<Props, State> {
if (this.isURL(pastedText)) { if (this.isURL(pastedText)) {
window.inboxStore?.dispatch( window.inboxStore?.dispatch(
updateConfirmModal({ updateConfirmModal({
shouldShowConfirm: () => !window.getSettingValue('link-preview-setting'), shouldShowConfirm: !window.getSettingValue('link-preview-setting'),
title: window.i18n('linkPreviewsTitle'), title: window.i18n('linkPreviewsTitle'),
message: window.i18n('linkPreviewsConfirmMessage'), message: window.i18n('linkPreviewsConfirmMessage'),
okTheme: SessionButtonColor.Danger, okTheme: SessionButtonColor.Danger,

@ -20,7 +20,7 @@ import { ToastUtils } from '../../../session/utils';
import { TypingBubble } from '../../conversation/TypingBubble'; import { TypingBubble } from '../../conversation/TypingBubble';
import { getConversationController } from '../../../session/conversations'; import { getConversationController } from '../../../session/conversations';
import { MessageModel } from '../../../models/message'; import { MessageModel } from '../../../models/message';
import { MessageRegularProps } from '../../../models/messageType'; import { MessageRegularProps, QuoteClickOptions } from '../../../models/messageType';
import { getMessageById, getMessagesBySentAt } from '../../../data/data'; import { getMessageById, getMessagesBySentAt } from '../../../data/data';
import autoBind from 'auto-bind'; import autoBind from 'auto-bind';
import { ConversationTypeEnum } from '../../../models/conversation'; import { ConversationTypeEnum } from '../../../models/conversation';
@ -238,7 +238,6 @@ export class SessionMessagesList extends React.Component<Props, State> {
key={`unread-indicator-${messageProps.propsForMessage.id}`} key={`unread-indicator-${messageProps.propsForMessage.id}`}
/> />
); );
console.warn('key', messageProps.propsForMessage.id);
currentMessageIndex = currentMessageIndex + 1; currentMessageIndex = currentMessageIndex + 1;
if (groupNotificationProps) { if (groupNotificationProps) {
@ -349,21 +348,14 @@ export class SessionMessagesList extends React.Component<Props, State> {
regularProps.isQuotedMessageToAnimate = messageId === this.state.animateQuotedMessageId; regularProps.isQuotedMessageToAnimate = messageId === this.state.animateQuotedMessageId;
if (regularProps.quote) { // tslint:disable-next-line: no-async-without-await
regularProps.quote.onClick = (options: { const onQuoteClick = regularProps.quote ? this.scrollToQuoteMessage : async () => {};
quoteAuthor: string;
quoteId: any;
referencedMessageNotFound: boolean;
}) => {
void this.scrollToQuoteMessage(options);
};
}
regularProps.nextMessageToPlay = this.state.nextMessageToPlay; regularProps.nextMessageToPlay = this.state.nextMessageToPlay;
regularProps.playableMessageIndex = playableMessageIndex; regularProps.playableMessageIndex = playableMessageIndex;
regularProps.playNextMessage = this.playNextMessage; regularProps.playNextMessage = this.playNextMessage;
return <Message {...regularProps} key={messageId} />; return <Message {...regularProps} onQuoteClick={onQuoteClick} key={messageId} />;
} }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -563,7 +555,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
this.updateReadMessages(); this.updateReadMessages();
} }
private async scrollToQuoteMessage(options: any = {}) { private async scrollToQuoteMessage(options: QuoteClickOptions) {
const { quoteAuthor, quoteId, referencedMessageNotFound } = options; const { quoteAuthor, quoteId, referencedMessageNotFound } = options;
// For simplicity's sake, we show the 'not found' toast no matter what if we were // For simplicity's sake, we show the 'not found' toast no matter what if we were

@ -50,7 +50,7 @@ interface State {
} }
interface ConfirmationDialogParams extends SessionConfirmDialogProps { interface ConfirmationDialogParams extends SessionConfirmDialogProps {
shouldShowConfirm: () => boolean | undefined; shouldShowConfirm: boolean | undefined;
} }
interface LocalSettingType { interface LocalSettingType {
@ -344,7 +344,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
comparisonValue: undefined, comparisonValue: undefined,
onClick: undefined, onClick: undefined,
confirmationDialogParams: { confirmationDialogParams: {
shouldShowConfirm: () => !window.getSettingValue('link-preview-setting'), shouldShowConfirm: !window.getSettingValue('link-preview-setting'),
title: window.i18n('linkPreviewsTitle'), title: window.i18n('linkPreviewsTitle'),
message: window.i18n('linkPreviewsConfirmMessage'), message: window.i18n('linkPreviewsConfirmMessage'),
okTheme: SessionButtonColor.Danger, okTheme: SessionButtonColor.Danger,
@ -405,19 +405,6 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
}, },
confirmationDialogParams: undefined, confirmationDialogParams: undefined,
}, },
{
id: 'media-permissions',
title: window.i18n('mediaPermissionsTitle'),
description: window.i18n('mediaPermissionsDescription'),
hidden: false,
type: SessionSettingType.Toggle,
category: SessionSettingCategory.Permissions,
setFn: window.toggleMediaPermissions,
content: undefined,
comparisonValue: undefined,
onClick: undefined,
confirmationDialogParams: undefined,
},
{ {
id: 'zoom-factor-setting', id: 'zoom-factor-setting',
title: window.i18n('zoomFactorSettingTitle'), title: window.i18n('zoomFactorSettingTitle'),

@ -6,10 +6,9 @@ interface Props extends SettingsViewProps {
// tslint:disable-next-line: react-unused-props-and-state // tslint:disable-next-line: react-unused-props-and-state
categoryTitle: string; categoryTitle: string;
// tslint:disable-next-line: react-unused-props-and-state // tslint:disable-next-line: react-unused-props-and-state
theme: DefaultTheme;
} }
const SettingsHeaderInner = (props: Props) => { export const SettingsHeader = (props: Props) => {
const { categoryTitle } = props; const { categoryTitle } = props;
return ( return (
<div className="session-settings-header"> <div className="session-settings-header">
@ -17,5 +16,3 @@ const SettingsHeaderInner = (props: Props) => {
</div> </div>
); );
}; };
export const SettingsHeader = withTheme(SettingsHeaderInner);

@ -943,7 +943,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const allProps: Array<MessageModelProps> = []; const allProps: Array<MessageModelProps> = [];
for (const nowRead of oldUnreadNowRead) { for (const nowRead of oldUnreadNowRead) {
allProps.push(nowRead.generateProps(false)); allProps.push(nowRead.getProps());
} }
window.inboxStore?.dispatch(conversationActions.messagesChanged(allProps)); window.inboxStore?.dispatch(conversationActions.messagesChanged(allProps));

@ -80,34 +80,29 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
window.contextMenuShown = false; window.contextMenuShown = false;
// this.generateProps(false); this.getProps();
} }
public getProps(): MessageModelProps { public getProps(): MessageModelProps {
const propsForTimerNotification = this.getPropsForTimerNotification(); perfStart(`getPropsMessage-${this.id}`);
const propsForGroupNotification = this.getPropsForGroupNotification();
const propsForGroupInvitation = this.getPropsForGroupInvitation();
const propsForDataExtractionNotification = this.getPropsForDataExtractionNotification();
const propsForSearchResult = this.getPropsForSearchResult();
const propsForMessage = this.getPropsForMessage();
const messageProps: MessageModelProps = { const messageProps: MessageModelProps = {
propsForMessage, propsForMessage: this.getPropsForMessage(),
propsForSearchResult, propsForSearchResult: this.getPropsForSearchResult(),
propsForDataExtractionNotification, propsForDataExtractionNotification: this.getPropsForDataExtractionNotification(),
propsForGroupInvitation, propsForGroupInvitation: this.getPropsForGroupInvitation(),
propsForGroupNotification, propsForGroupNotification: this.getPropsForGroupNotification(),
propsForTimerNotification, propsForTimerNotification: this.getPropsForTimerNotification(),
}; };
perfEnd(`getPropsMessage-${this.id}`, 'getPropsMessage');
return messageProps; return messageProps;
} }
// Keep props ready // Keep props ready
public generateProps(triggerEvent = true): MessageModelProps { public generateProps(): MessageModelProps {
const messageProps = this.getProps(); const messageProps = this.getProps();
if (triggerEvent) { window.inboxStore?.dispatch(conversationActions.messageChanged(messageProps));
window.inboxStore?.dispatch(conversationActions.messageChanged(messageProps));
}
return messageProps; return messageProps;
} }

@ -192,6 +192,11 @@ export const fillMessageAttributesWithDefaults = (
return defaulted; return defaulted;
}; };
export type QuoteClickOptions = {
quoteAuthor: string;
quoteId: number;
referencedMessageNotFound: boolean;
};
export interface MessageRegularProps { export interface MessageRegularProps {
disableMenu?: boolean; disableMenu?: boolean;
isDeletable: boolean; isDeletable: boolean;
@ -251,6 +256,7 @@ export interface MessageRegularProps {
onDeleteMessage: (messageId: string) => void; onDeleteMessage: (messageId: string) => void;
onShowDetail: () => void; onShowDetail: () => void;
markRead: (readAt: number) => Promise<void>; markRead: (readAt: number) => Promise<void>;
onQuoteClick: (options: QuoteClickOptions) => Promise<void>;
theme: DefaultTheme; theme: DefaultTheme;
playableMessageIndex?: number; playableMessageIndex?: number;

@ -61,7 +61,7 @@ async function handleGroupsAndContactsFromConfigMessage(
const didWeHandleAConfigurationMessageAlready = const didWeHandleAConfigurationMessageAlready =
(await getItemById(hasSyncedInitialConfigurationItem))?.value || false; (await getItemById(hasSyncedInitialConfigurationItem))?.value || false;
if (didWeHandleAConfigurationMessageAlready) { if (didWeHandleAConfigurationMessageAlready) {
window?.log?.warn( window?.log?.info(
'Dropping configuration contacts/groups change as we already handled one... ' 'Dropping configuration contacts/groups change as we already handled one... '
); );
return; return;
@ -73,7 +73,7 @@ async function handleGroupsAndContactsFromConfigMessage(
const numberClosedGroup = configMessage.closedGroups?.length || 0; const numberClosedGroup = configMessage.closedGroups?.length || 0;
window?.log?.warn( window?.log?.info(
`Received ${numberClosedGroup} closed group on configuration. Creating them... ` `Received ${numberClosedGroup} closed group on configuration. Creating them... `
); );

@ -198,8 +198,9 @@ async function getMessages(
}); });
// Set first member of series here. // Set first member of series here.
const messageModelsProps: Array<SortedMessageModelProps> = messageSet.models.map(m => { const messageModelsProps: Array<SortedMessageModelProps> = [];
return { ...m.getProps(), firstMessageOfSeries: true }; messageSet.models.forEach(m => {
messageModelsProps.push({ ...m.getProps(), firstMessageOfSeries: true });
}); });
const isPublic = conversation.isPublic(); const isPublic = conversation.isPublic();
@ -262,14 +263,15 @@ const fetchMessagesForConversation = createAsyncThunk(
const time = afterTimestamp - beforeTimestamp; const time = afterTimestamp - beforeTimestamp;
window?.log?.info(`Loading ${messagesProps.length} messages took ${time}ms to load.`); window?.log?.info(`Loading ${messagesProps.length} messages took ${time}ms to load.`);
const mapped = messagesProps.map(m => {
return {
...m,
firstMessageOfSeries: true,
};
});
return { return {
conversationKey, conversationKey,
messagesProps: messagesProps.map(m => { messagesProps: mapped,
return {
...m,
firstMessageOfSeries: true,
};
}),
}; };
} }
); );
@ -521,9 +523,9 @@ function sortMessages(
// we order by serverTimestamp for public convos // we order by serverTimestamp for public convos
// be sure to update the sorting order to fetch messages from the DB too at getMessagesByConversation // be sure to update the sorting order to fetch messages from the DB too at getMessagesByConversation
if (isPublic) { if (isPublic) {
return messages.sort( return messages.sort((a, b) => {
(a: any, b: any) => b.attributes.serverTimestamp - a.attributes.serverTimestamp return (b.propsForMessage.serverTimestamp || 0) - (a.propsForMessage.serverTimestamp || 0);
); });
} }
if (messages.some(n => !n.propsForMessage.timestamp && !n.propsForMessage.receivedAt)) { if (messages.some(n => !n.propsForMessage.timestamp && !n.propsForMessage.receivedAt)) {
throw new Error('Found some messages without any timestamp set'); throw new Error('Found some messages without any timestamp set');
@ -532,9 +534,9 @@ function sortMessages(
// for non public convos, we order by sent_at or received_at timestamp. // for non public convos, we order by sent_at or received_at timestamp.
// we assume that a message has either a sent_at or a received_at field set. // we assume that a message has either a sent_at or a received_at field set.
const messagesSorted = messages.sort( const messagesSorted = messages.sort(
(a: any, b: any) => (a, b) =>
(b.attributes.sent_at || b.attributes.received_at) - (b.propsForMessage.timestamp || b.propsForMessage.receivedAt || 0) -
(a.attributes.sent_at || a.attributes.received_at) (a.propsForMessage.timestamp || a.propsForMessage.receivedAt || 0)
); );
return messagesSorted; return messagesSorted;
@ -737,7 +739,7 @@ export function reducer(
if (conversationKey === state.selectedConversation) { if (conversationKey === state.selectedConversation) {
return { return {
...state, ...state,
messages: { ...messagesProps }, messages: messagesProps,
}; };
} }
return state; return state;

Loading…
Cancel
Save