Fix for missing replacement text in bodyRanges

This commit is contained in:
Josh Perez 2021-03-05 12:57:09 -05:00 committed by Josh Perez
parent dab5386207
commit 3cc6c5f5ad
6 changed files with 72 additions and 38 deletions

View file

@ -2,10 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { DataMessageClass } from './textsecure.d'; import { DataMessageClass } from './textsecure.d';
import { MessageAttributesType } from './model-types.d';
import { WhatIsThis } from './window.d'; import { WhatIsThis } from './window.d';
import { assert } from './util/assert'; import { assert } from './util/assert';
export async function startApp(): Promise<void> { export async function startApp(): Promise<void> {
window.attachmentDownloadQueue = [];
try { try {
window.log.info('Initializing SQL in renderer'); window.log.info('Initializing SQL in renderer');
await window.sqlInitializer.initialize(); await window.sqlInitializer.initialize();
@ -2073,11 +2075,20 @@ export async function startApp(): Promise<void> {
attachmentsToDownload.length, attachmentsToDownload.length,
attachmentDownloadQueue.length attachmentDownloadQueue.length
); );
await Promise.all( window.attachmentDownloadQueue = undefined;
const messagesWithDownloads = await Promise.all(
attachmentsToDownload.map(message => attachmentsToDownload.map(message =>
message.queueAttachmentDownloads() message.queueAttachmentDownloads()
) )
); );
const messagesToSave: Array<MessageAttributesType> = [];
messagesWithDownloads.forEach((shouldSave, messageKey) => {
if (shouldSave) {
const message = attachmentsToDownload[messageKey];
messagesToSave.push(message.attributes);
}
});
await window.Signal.Data.saveMessages(messagesToSave, {});
} }
}, 500); }, 500);

View file

@ -3614,8 +3614,15 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
(this.getConversation()!.getAccepted() || message.isOutgoing()) && (this.getConversation()!.getAccepted() || message.isOutgoing()) &&
!shouldHoldOffDownload !shouldHoldOffDownload
) { ) {
window.attachmentDownloadQueue = window.attachmentDownloadQueue || []; if (window.attachmentDownloadQueue) {
window.attachmentDownloadQueue.unshift(message); window.attachmentDownloadQueue.unshift(message);
window.log.info(
'Adding to attachmentDownloadQueue',
message.get('sent_at')
);
} else {
await message.queueAttachmentDownloads();
}
} }
// Does this message have any pending, previously-received associated reactions? // Does this message have any pending, previously-received associated reactions?

View file

@ -28,6 +28,8 @@ import {
getConversationSelector, getConversationSelector,
} from './conversations'; } from './conversations';
import { BodyRangeType } from '../../types/Util';
export const getSearch = (state: StateType): SearchStateType => state.search; export const getSearch = (state: StateType): SearchStateType => state.search;
export const getQuery = createSelector( export const getQuery = createSelector(
@ -110,29 +112,6 @@ export const getSearchResults = createSelector(
} }
); );
export function _messageSearchResultSelector(
message: MessageSearchResultType,
from: ConversationType,
to: ConversationType,
searchConversationId?: string,
selectedMessageId?: string
): MessageSearchResultPropsDataType {
return {
from,
to,
id: message.id,
conversationId: message.conversationId,
sentAt: message.sent_at,
snippet: message.snippet,
bodyRanges: message.bodyRanges,
body: message.body,
isSelected: Boolean(selectedMessageId && message.id === selectedMessageId),
isSearchingInConversation: Boolean(searchConversationId),
};
}
// A little optimization to reset our selector cache whenever high-level application data // A little optimization to reset our selector cache whenever high-level application data
// changes: regionCode and userNumber. // changes: regionCode and userNumber.
type CachedMessageSearchResultSelectorType = ( type CachedMessageSearchResultSelectorType = (
@ -142,18 +121,58 @@ type CachedMessageSearchResultSelectorType = (
searchConversationId?: string, searchConversationId?: string,
selectedMessageId?: string selectedMessageId?: string
) => MessageSearchResultPropsDataType; ) => MessageSearchResultPropsDataType;
export const getCachedSelectorForMessageSearchResult = createSelector( export const getCachedSelectorForMessageSearchResult = createSelector(
getUserConversationId, getUserConversationId,
(): CachedMessageSearchResultSelectorType => { getConversationSelector,
(
_,
conversationSelector: GetConversationByIdType
): CachedMessageSearchResultSelectorType => {
// Note: memoizee will check all parameters provided, and only run our selector // Note: memoizee will check all parameters provided, and only run our selector
// if any of them have changed. // if any of them have changed.
return memoizee(_messageSearchResultSelector, { max: 500 }); return memoizee(
(
message: MessageSearchResultType,
from: ConversationType,
to: ConversationType,
searchConversationId?: string,
selectedMessageId?: string
) => {
const bodyRanges = message.bodyRanges || [];
return {
from,
to,
id: message.id,
conversationId: message.conversationId,
sentAt: message.sent_at,
snippet: message.snippet,
bodyRanges: bodyRanges.map((bodyRange: BodyRangeType) => {
const conversation = conversationSelector(bodyRange.mentionUuid);
return {
...bodyRange,
replacementText: conversation.title,
};
}),
body: message.body,
isSelected: Boolean(
selectedMessageId && message.id === selectedMessageId
),
isSearchingInConversation: Boolean(searchConversationId),
};
},
{ max: 500 }
);
} }
); );
type GetMessageSearchResultByIdType = ( type GetMessageSearchResultByIdType = (
id: string id: string
) => MessageSearchResultPropsDataType | undefined; ) => MessageSearchResultPropsDataType | undefined;
export const getMessageSearchResultSelector = createSelector( export const getMessageSearchResultSelector = createSelector(
getCachedSelectorForMessageSearchResult, getCachedSelectorForMessageSearchResult,
getMessageSearchResultLookup, getMessageSearchResultLookup,

View file

@ -204,9 +204,6 @@ describe('both/state/selectors/search', () => {
...state, ...state,
conversations: { conversations: {
...state.conversations, ...state.conversations,
conversationLookup: {
...state.conversations.conversationLookup,
},
}, },
}; };
const secondSelector = getMessageSearchResultSelector(secondState); const secondSelector = getMessageSearchResultSelector(secondState);

View file

@ -8,17 +8,17 @@ import { createWaitBatcher } from './waitBatcher';
export const updateMessageBatcher = createBatcher<MessageAttributesType>({ export const updateMessageBatcher = createBatcher<MessageAttributesType>({
wait: 500, wait: 500,
maxSize: 50, maxSize: 50,
processBatch: async (messages: Array<MessageAttributesType>) => { processBatch: async (messageAttrs: Array<MessageAttributesType>) => {
window.log.info('updateMessageBatcher', messages.length); window.log.info('updateMessageBatcher', messageAttrs.length);
await window.Signal.Data.saveMessages(messages, {}); await window.Signal.Data.saveMessages(messageAttrs, {});
}, },
}); });
export const saveNewMessageBatcher = createWaitBatcher<MessageAttributesType>({ export const saveNewMessageBatcher = createWaitBatcher<MessageAttributesType>({
wait: 500, wait: 500,
maxSize: 30, maxSize: 30,
processBatch: async (messages: Array<MessageAttributesType>) => { processBatch: async (messageAttrs: Array<MessageAttributesType>) => {
window.log.info('saveNewMessageBatcher', messages.length); window.log.info('saveNewMessageBatcher', messageAttrs.length);
await window.Signal.Data.saveMessages(messages, { forceSave: true }); await window.Signal.Data.saveMessages(messageAttrs, { forceSave: true });
}, },
}); });

2
ts/window.d.ts vendored
View file

@ -137,7 +137,7 @@ declare global {
WhatIsThis: WhatIsThis; WhatIsThis: WhatIsThis;
attachmentDownloadQueue: Array<MessageModel>; attachmentDownloadQueue: Array<MessageModel> | undefined;
baseAttachmentsPath: string; baseAttachmentsPath: string;
baseStickersPath: string; baseStickersPath: string;
baseTempPath: string; baseTempPath: string;