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

@ -13,7 +13,7 @@ import { ConversationTypeEnum } from '../../models/conversation';
import { useEncryptedFileFetch } from '../../hooks/useEncryptedFileFetch';
interface QuoteProps {
export type QuotePropsWithoutListener = {
attachment?: QuotedAttachmentType;
authorPhoneNumber: string;
authorProfileName?: string;
@ -24,10 +24,13 @@ interface QuoteProps {
convoId: string;
isPublic?: boolean;
withContentAbove: boolean;
onClick?: (e: any) => void;
text: string;
referencedMessageNotFound: boolean;
}
};
export type QuotePropsWithListener = QuotePropsWithoutListener & {
onClick?: (e: any) => void;
};
export interface QuotedAttachmentType {
contentType: MIME.MIMEType;
@ -43,7 +46,7 @@ interface Attachment {
objectUrl?: string;
}
function validateQuote(quote: QuoteProps): boolean {
function validateQuote(quote: QuotePropsWithoutListener): boolean {
if (quote.text) {
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 handleImageErrorBound = null;

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

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

@ -25,7 +25,7 @@ export const SessionToggle = (props: Props) => {
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
const closeConfirmModal = () => {
dispatch(updateConfirmModal(null));

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

@ -20,7 +20,7 @@ import { ToastUtils } from '../../../session/utils';
import { TypingBubble } from '../../conversation/TypingBubble';
import { getConversationController } from '../../../session/conversations';
import { MessageModel } from '../../../models/message';
import { MessageRegularProps } from '../../../models/messageType';
import { MessageRegularProps, QuoteClickOptions } from '../../../models/messageType';
import { getMessageById, getMessagesBySentAt } from '../../../data/data';
import autoBind from 'auto-bind';
import { ConversationTypeEnum } from '../../../models/conversation';
@ -238,7 +238,6 @@ export class SessionMessagesList extends React.Component<Props, State> {
key={`unread-indicator-${messageProps.propsForMessage.id}`}
/>
);
console.warn('key', messageProps.propsForMessage.id);
currentMessageIndex = currentMessageIndex + 1;
if (groupNotificationProps) {
@ -349,21 +348,14 @@ export class SessionMessagesList extends React.Component<Props, State> {
regularProps.isQuotedMessageToAnimate = messageId === this.state.animateQuotedMessageId;
if (regularProps.quote) {
regularProps.quote.onClick = (options: {
quoteAuthor: string;
quoteId: any;
referencedMessageNotFound: boolean;
}) => {
void this.scrollToQuoteMessage(options);
};
}
// tslint:disable-next-line: no-async-without-await
const onQuoteClick = regularProps.quote ? this.scrollToQuoteMessage : async () => {};
regularProps.nextMessageToPlay = this.state.nextMessageToPlay;
regularProps.playableMessageIndex = playableMessageIndex;
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();
}
private async scrollToQuoteMessage(options: any = {}) {
private async scrollToQuoteMessage(options: QuoteClickOptions) {
const { quoteAuthor, quoteId, referencedMessageNotFound } = options;
// 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 {
shouldShowConfirm: () => boolean | undefined;
shouldShowConfirm: boolean | undefined;
}
interface LocalSettingType {
@ -344,7 +344,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
comparisonValue: undefined,
onClick: undefined,
confirmationDialogParams: {
shouldShowConfirm: () => !window.getSettingValue('link-preview-setting'),
shouldShowConfirm: !window.getSettingValue('link-preview-setting'),
title: window.i18n('linkPreviewsTitle'),
message: window.i18n('linkPreviewsConfirmMessage'),
okTheme: SessionButtonColor.Danger,
@ -405,19 +405,6 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
},
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',
title: window.i18n('zoomFactorSettingTitle'),

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

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

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

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

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

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

Loading…
Cancel
Save