Compare commits

...

9 Commits
main ... 5.59.x

Author SHA1 Message Date
Scott Nonnenberg 19f26cc423 v5.59.0 2022-09-14 17:57:35 -07:00
Scott Nonnenberg 60815fba6f Update strings 2022-09-14 17:57:02 -07:00
Jamie Kyle 51f7034cab
Fix storyviewer title for groups 2022-09-14 17:33:18 -07:00
automated-signal 3b33ec74a6
Separate flag for cdsi in beta channel
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-13 21:27:10 -07:00
Scott Nonnenberg 1f010c75c6
Improve logging in handleDataMessage and contact sync 2022-09-13 21:09:28 -07:00
automated-signal 4cb52b75f2
Center "Disappearing Messages" in Create Group
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-12 16:55:54 -07:00
automated-signal 0917f22f0a
Never pass negative speaker height to RingRTC
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-12 15:57:06 -06:00
automated-signal 2454432d92
Fixed positioning of emoji popper - avoids range error
Co-authored-by: Alvaro <110414366+alvaro-signal@users.noreply.github.com>
2022-09-12 09:11:10 -07:00
automated-signal dff3633257
Update electron to 20.1.3
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-08 18:09:19 -07:00
15 changed files with 101 additions and 103 deletions

View File

@ -552,7 +552,7 @@
"description": "Alt text for staged attachments" "description": "Alt text for staged attachments"
}, },
"cdsMirroringErrorToast": { "cdsMirroringErrorToast": {
"message": "El Escritorio ha encontrado una inconsistencia del Servicio de descubrimiento de contactos.", "message": "Desktop ha encontrado una inconsistencia del Servicio de descubrimiento de contactos.",
"description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests." "description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests."
}, },
"decryptionErrorToast": { "decryptionErrorToast": {

View File

@ -552,7 +552,7 @@
"description": "Alt text for staged attachments" "description": "Alt text for staged attachments"
}, },
"cdsMirroringErrorToast": { "cdsMirroringErrorToast": {
"message": "Рабочий стол столкнулся с несогласованностью Службы обнаружения контактов.", "message": "Signal Desktop столкнулся с несогласованностью Службы обнаружения контактов.",
"description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests." "description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests."
}, },
"decryptionErrorToast": { "decryptionErrorToast": {
@ -5568,7 +5568,7 @@
"description": "Button label to delete a story" "description": "Button label to delete a story"
}, },
"SendStoryModal__confirm-remove-group": { "SendStoryModal__confirm-remove-group": {
"message": "Удалить историю? Это приведет к удалению истории из вашего списка, но вы по-прежнему сможете просматривать истории этой группы.", "message": "Удалить историю? Это приведёт к удалению истории из вашего списка, но вы по-прежнему сможете просматривать истории этой группы.",
"description": "Confirmation body for removing a group story" "description": "Confirmation body for removing a group story"
}, },
"Stories__settings-toggle--title": { "Stories__settings-toggle--title": {
@ -5604,7 +5604,7 @@
"description": "Aria label for unmuting stories" "description": "Aria label for unmuting stories"
}, },
"StoryViewer__views-off": { "StoryViewer__views-off": {
"message": "Просмотр отключен", "message": "Просмотры отключены",
"description": "When the user has read receipts turned off" "description": "When the user has read receipts turned off"
}, },
"StoryDetailsModal__sent-time": { "StoryDetailsModal__sent-time": {

View File

@ -5360,15 +5360,15 @@
"description": "Additional information about signal connections and the stories they can see" "description": "Additional information about signal connections and the stories they can see"
}, },
"Stories__title": { "Stories__title": {
"message": "Історії", "message": "Сторіз",
"description": "Title for the stories list" "description": "Title for the stories list"
}, },
"Stories__mine": { "Stories__mine": {
"message": "Мої історії", "message": "Мої сторіз",
"description": "Label for your stories" "description": "Label for your stories"
}, },
"Stories__add": { "Stories__add": {
"message": "Додати історію", "message": "Додати сторі",
"description": "Description hint to add a story" "description": "Description hint to add a story"
}, },
"Stories__add-story--text": { "Stories__add-story--text": {
@ -5380,15 +5380,15 @@
"description": "Label to create a new multimedia story" "description": "Label to create a new multimedia story"
}, },
"Stories__hidden-stories": { "Stories__hidden-stories": {
"message": "Приховані історії", "message": "Приховані сторіз",
"description": "Button label to go to hidden stories pane" "description": "Button label to go to hidden stories pane"
}, },
"Stories__list-empty": { "Stories__list-empty": {
"message": "Нових історій немає", "message": "Нових сторіз немає",
"description": "Description for when there are no stories to show" "description": "Description for when there are no stories to show"
}, },
"Stories__placeholder--text": { "Stories__placeholder--text": {
"message": "Клацніть для перегляду історії", "message": "Клацніть для перегляду сторі",
"description": "Placeholder label for the story view" "description": "Placeholder label for the story view"
}, },
"Stories__from-to-group": { "Stories__from-to-group": {
@ -5408,11 +5408,11 @@
"description": "Toast message" "description": "Toast message"
}, },
"StoriesSettings__title": { "StoriesSettings__title": {
"message": "Налаштування історії", "message": "Налаштування сторі",
"description": "Title for the story settings modal" "description": "Title for the story settings modal"
}, },
"StoriesSettings__new-list": { "StoriesSettings__new-list": {
"message": "Нова приватна історія", "message": "Нова приватна сторі",
"description": "Label to create a new private story list" "description": "Label to create a new private story list"
}, },
"StoriesSettings__viewers--singular": { "StoriesSettings__viewers--singular": {
@ -5424,7 +5424,7 @@
"description": "More than one viewer" "description": "More than one viewer"
}, },
"StoriesSettings__who-can-see": { "StoriesSettings__who-can-see": {
"message": "Хто може бачити цю історію", "message": "Хто може бачити цю сторі",
"description": "Title for the who can see this story section" "description": "Title for the who can see this story section"
}, },
"StoriesSettings__add-viewer": { "StoriesSettings__add-viewer": {
@ -5440,7 +5440,7 @@
"description": "Title of the confirmation dialog, has a person's name" "description": "Title of the confirmation dialog, has a person's name"
}, },
"StoriesSettings__remove--body": { "StoriesSettings__remove--body": {
"message": "Ця особа більше не бачитиме ваших історій.", "message": "Ця особа більше не бачитиме вашу сторі.",
"description": "Body of the confirmation dialog to remove someone from a private distribution list" "description": "Body of the confirmation dialog to remove someone from a private distribution list"
}, },
"StoriesSettings__replies-reactions--title": { "StoriesSettings__replies-reactions--title": {
@ -5456,7 +5456,7 @@
"description": "Description of checkbox to allow or disallow replies to your stories" "description": "Description of checkbox to allow or disallow replies to your stories"
}, },
"StoriesSettings__delete-list": { "StoriesSettings__delete-list": {
"message": "Видалити приватну історію", "message": "Видалити приватну сторі",
"description": "Button label to delete a private distribution list" "description": "Button label to delete a private distribution list"
}, },
"StoriesSettings__delete-list--confirm": { "StoriesSettings__delete-list--confirm": {
@ -5472,11 +5472,11 @@
"description": "Modal title when naming a private distribution list" "description": "Modal title when naming a private distribution list"
}, },
"StoriesSettings__name-placeholder": { "StoriesSettings__name-placeholder": {
"message": "Назва історії (обов'язкова)", "message": "Назва сторі (обов'язкова)",
"description": "Placeholder for input field" "description": "Placeholder for input field"
}, },
"StoriesSettings__hide-story": { "StoriesSettings__hide-story": {
"message": "Сховати історію від", "message": "Приховати сторі від",
"description": "Modal title when hiding people from my stories" "description": "Modal title when hiding people from my stories"
}, },
"StoriesSettings__mine__all--label": { "StoriesSettings__mine__all--label": {
@ -5516,7 +5516,7 @@
"description": "Learn more link to learn about who can view your story" "description": "Learn more link to learn about who can view your story"
}, },
"StoriesSettings__context-menu": { "StoriesSettings__context-menu": {
"message": "Налаштування історії", "message": "Налаштування сторі",
"description": "Button label to get to story settings" "description": "Button label to get to story settings"
}, },
"SendStoryModal__choose-who-can-view": { "SendStoryModal__choose-who-can-view": {
@ -5536,7 +5536,7 @@
"description": "button to create a new distribution list to send story to" "description": "button to create a new distribution list to send story to"
}, },
"SendStoryModal__new-private--title": { "SendStoryModal__new-private--title": {
"message": "Нова приватна історія", "message": "Нова приватна сторі",
"description": "Create a new distribution list" "description": "Create a new distribution list"
}, },
"SendStoryModal__new-private--description": { "SendStoryModal__new-private--description": {
@ -5592,7 +5592,7 @@
"description": "Button label to reply to a story" "description": "Button label to reply to a story"
}, },
"StoryViewer__reply-group": { "StoryViewer__reply-group": {
"message": "Відповісти на історію групи", "message": "Відповісти на сторі групи",
"description": "Button label to reply to a group story" "description": "Button label to reply to a group story"
}, },
"StoryViewer__mute": { "StoryViewer__mute": {
@ -5636,23 +5636,23 @@
"description": "Title for replies tab" "description": "Title for replies tab"
}, },
"StoryViewsNRepliesModal__react": { "StoryViewsNRepliesModal__react": {
"message": "Реагувати на історію", "message": "Реагувати на сторі",
"description": "aria-label for reaction button" "description": "aria-label for reaction button"
}, },
"StoryViewsNRepliesModal__reacted": { "StoryViewsNRepliesModal__reacted": {
"message": "Зреагував на історію", "message": "Реагує на сторі",
"description": "Description of someone reacting to a story" "description": "Description of someone reacting to a story"
}, },
"StoryListItem__label": { "StoryListItem__label": {
"message": "Історія", "message": "Сторі",
"description": "aria-label for the story list button" "description": "aria-label for the story list button"
}, },
"StoryListItem__unhide": { "StoryListItem__unhide": {
"message": "Показати історії", "message": "Показати сторіз",
"description": "Label for menu item to un-hide the story" "description": "Label for menu item to un-hide the story"
}, },
"StoryListItem__hide": { "StoryListItem__hide": {
"message": "Сховати історію", "message": "Сховати сторі",
"description": "Label for menu item to hide the story" "description": "Label for menu item to hide the story"
}, },
"StoryListItem__go-to-chat": { "StoryListItem__go-to-chat": {
@ -5668,7 +5668,7 @@
"description": "Label for menu item to get a story's information" "description": "Label for menu item to get a story's information"
}, },
"StoryListItem__hide-modal--body": { "StoryListItem__hide-modal--body": {
"message": "Сховати історію? Оновлення історій від $name$ більше не з'являтимуться нагорі списку історій.", "message": "Сховати сторі? Оновлення сторі від користувача $name$ більше не з'являтимуться нагорі списку сторіз.",
"description": "Body for the confirmation dialog for hiding a story" "description": "Body for the confirmation dialog for hiding a story"
}, },
"StoryListItem__hide-modal--confirm": { "StoryListItem__hide-modal--confirm": {
@ -5768,15 +5768,15 @@
"description": "Title for the link preview tooltip" "description": "Title for the link preview tooltip"
}, },
"Quote__story": { "Quote__story": {
"message": "Історія", "message": "Сторі",
"description": "Title for replies to stories" "description": "Title for replies to stories"
}, },
"Quote__story-reaction": { "Quote__story-reaction": {
"message": "Реакція на історію від $name$", "message": "Реакція на сторі від $name$",
"description": "Label for when a person reacts to a story" "description": "Label for when a person reacts to a story"
}, },
"Quote__story-reaction--single": { "Quote__story-reaction--single": {
"message": "Реакції на історію", "message": "Реакція на сторі",
"description": "Used whenever we can't find a user's first name" "description": "Used whenever we can't find a user's first name"
}, },
"Quote__story-unavailable": { "Quote__story-unavailable": {

View File

@ -4,7 +4,7 @@
"description": "Private messaging from your desktop", "description": "Private messaging from your desktop",
"desktopName": "signal.desktop", "desktopName": "signal.desktop",
"repository": "https://github.com/signalapp/Signal-Desktop.git", "repository": "https://github.com/signalapp/Signal-Desktop.git",
"version": "5.59.0-beta.1", "version": "5.59.0",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"author": { "author": {
"name": "Signal Messenger, LLC", "name": "Signal Messenger, LLC",
@ -272,7 +272,7 @@
"cross-env": "5.2.0", "cross-env": "5.2.0",
"css-loader": "3.2.0", "css-loader": "3.2.0",
"debug": "4.3.3", "debug": "4.3.3",
"electron": "20.1.0", "electron": "20.1.3",
"electron-builder": "23.0.8", "electron-builder": "23.0.8",
"electron-mocha": "11.0.2", "electron-mocha": "11.0.2",
"electron-notarize": "1.2.1", "electron-notarize": "1.2.1",

View File

@ -5140,6 +5140,7 @@ button.module-image__border-overlay:focus {
&__expire-timer { &__expire-timer {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
margin: 0 16px 16px 16px; margin: 0 16px 16px 16px;

View File

@ -10,6 +10,7 @@ export type ConfigKeyType =
| 'desktop.announcementGroup' | 'desktop.announcementGroup'
| 'desktop.calling.audioLevelForSpeaking' | 'desktop.calling.audioLevelForSpeaking'
| 'desktop.cdsi' | 'desktop.cdsi'
| 'desktop.cdsi.beta'
| 'desktop.cdsi.returnAcisWithoutUaks' | 'desktop.cdsi.returnAcisWithoutUaks'
| 'desktop.cdsi.mirroring' | 'desktop.cdsi.mirroring'
| 'desktop.clientExpiration' | 'desktop.clientExpiration'

View File

@ -380,7 +380,10 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
break; break;
} }
setGroupCallVideoRequest(videoRequest, gridParticipantHeight); setGroupCallVideoRequest(
videoRequest,
clamp(gridParticipantHeight, 0, MAX_FRAME_HEIGHT)
);
}, [ }, [
devicePixelRatio, devicePixelRatio,
gridParticipantHeight, gridParticipantHeight,

View File

@ -584,12 +584,12 @@ export const StoryViewer = ({
/> />
)} )}
<div className="StoryViewer__meta--title"> <div className="StoryViewer__meta--title">
{group {(group &&
? i18n('Stories__from-to-group', { i18n('Stories__from-to-group', {
name: title, name: isMe ? i18n('you') : title,
group: group.title, group: group.title,
}) })) ||
: title} (isMe ? i18n('you') : title)}
</div> </div>
<MessageTimestamp <MessageTimestamp
i18n={i18n} i18n={i18n}

View File

@ -2065,11 +2065,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const conversation = window.ConversationController.get(conversationId)!; const conversation = window.ConversationController.get(conversationId)!;
const idLog = conversation.idForLogging(); const idLog = `handleDataMessage/${conversation.idForLogging()} ${message.idForLogging()}`;
await conversation.queueJob('handleDataMessage', async () => { await conversation.queueJob('handleDataMessage', async () => {
log.info( log.info(`${idLog}: starting processing in queue`);
`handleDataMessage/${idLog}: processing message ${message.idForLogging()}`
);
if ( if (
isStory(message.attributes) && isStory(message.attributes) &&
@ -2078,7 +2076,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}) })
) { ) {
log.info( log.info(
`handleDataMessage/${idLog}: dropping story from !accepted`, `${idLog}: dropping story from !accepted`,
this.getSenderIdentifier() this.getSenderIdentifier()
); );
confirm(); confirm();
@ -2090,13 +2088,10 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
this.getSenderIdentifier() this.getSenderIdentifier()
)?.attributes; )?.attributes;
if (inMemoryMessage) { if (inMemoryMessage) {
log.info( log.info(`${idLog}: cache hit`, this.getSenderIdentifier());
`handleDataMessage/${idLog}: cache hit`,
this.getSenderIdentifier()
);
} else { } else {
log.info( log.info(
`handleDataMessage/${idLog}: duplicate check db lookup needed`, `${idLog}: duplicate check db lookup needed`,
this.getSenderIdentifier() this.getSenderIdentifier()
); );
} }
@ -2112,17 +2107,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
this.attributes.storyDistributionListId)); this.attributes.storyDistributionListId));
if (isDuplicateMessage) { if (isDuplicateMessage) {
log.warn( log.warn(`${idLog}: Received duplicate message`, this.idForLogging());
`handleDataMessage/${idLog}: Received duplicate message`,
this.idForLogging()
);
confirm(); confirm();
return; return;
} }
if (type === 'outgoing') { if (type === 'outgoing') {
if (isUpdate && existingMessage) { if (isUpdate && existingMessage) {
log.info( log.info(
`handleDataMessage/${idLog}: Updating message ${message.idForLogging()} with received transcript` `${idLog}: Updating message ${message.idForLogging()} with received transcript`
); );
const toUpdate = window.MessageController.register( const toUpdate = window.MessageController.register(
@ -2198,7 +2190,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
} }
if (isUpdate) { if (isUpdate) {
log.warn( log.warn(
`handleDataMessage/${idLog}: Received update transcript, but no existing entry for message ${message.idForLogging()}. Dropping.` `${idLog}: Received update transcript, but no existing entry for message ${message.idForLogging()}. Dropping.`
); );
confirm(); confirm();
@ -2206,7 +2198,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
} }
if (existingMessage) { if (existingMessage) {
log.warn( log.warn(
`handleDataMessage/${idLog}: Received duplicate transcript for message ${message.idForLogging()}, but it was not an update transcript. Dropping.` `${idLog}: Received duplicate transcript for message ${message.idForLogging()}, but it was not an update transcript. Dropping.`
); );
confirm(); confirm();
@ -2273,7 +2265,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
} catch (error) { } catch (error) {
const errorText = error && error.stack ? error.stack : error; const errorText = error && error.stack ? error.stack : error;
log.error( log.error(
`handleDataMessage/${idLog}: Failed to process group update as part of message ${message.idForLogging()}: ${errorText}` `${idLog}: Failed to process group update as part of message ${message.idForLogging()}: ${errorText}`
); );
throw error; throw error;
} }
@ -2300,7 +2292,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
(sourceUuid && window.storage.blocked.isUuidBlocked(sourceUuid)); (sourceUuid && window.storage.blocked.isUuidBlocked(sourceUuid));
if (isBlocked) { if (isBlocked) {
log.info( log.info(
`handleDataMessage/${idLog}: Dropping message from blocked sender. hasGroupV2Prop: ${hasGroupV2Prop}` `${idLog}: Dropping message from blocked sender. hasGroupV2Prop: ${hasGroupV2Prop}`
); );
confirm(); confirm();
@ -2320,7 +2312,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
(sourceUuid && !conversation.hasMember(new UUID(sourceUuid)))) (sourceUuid && !conversation.hasMember(new UUID(sourceUuid))))
) { ) {
log.warn( log.warn(
`Received message destined for group ${conversation.idForLogging()}, which we or the sender are not a part of. Dropping.` `${idLog}: Received message destined for group, which we or the sender are not a part of. Dropping.`
); );
confirm(); confirm();
return; return;
@ -2396,7 +2388,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (initialMessage.storyContext && !storyQuote) { if (initialMessage.storyContext && !storyQuote) {
log.warn( log.warn(
`handleDataMessage/${idLog}: Received storyContext message but no matching story. Dropping.` `${idLog}: Received storyContext message but no matching story. Dropping.`
); );
confirm(); confirm();
@ -2518,7 +2510,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
hash = computeHash(loadedAttachment.data); hash = computeHash(loadedAttachment.data);
} }
} catch (err) { } catch (err) {
log.info('handleDataMessage: group avatar download failed'); log.info(`${idLog}: group avatar download failed`);
} }
} }
@ -2558,7 +2550,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
pendingGroupUpdate.avatarUpdated = true; pendingGroupUpdate.avatarUpdated = true;
} else { } else {
log.info( log.info(
'handleDataMessage: Group avatar hash matched; not replacing group avatar' `${idLog}: Group avatar hash matched; not replacing group avatar`
); );
} }
@ -2588,7 +2580,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (!inGroup) { if (!inGroup) {
const senderString = sender ? sender.idForLogging() : null; const senderString = sender ? sender.idForLogging() : null;
log.info( log.info(
`Got 'left' message from someone not in group: ${senderString}. Dropping.` `${idLog}: Got 'left' message from someone not in group: ${senderString}. Dropping.`
); );
return; return;
} }
@ -2614,9 +2606,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// message.set call and after GroupV1 processing to make sure all possible // message.set call and after GroupV1 processing to make sure all possible
// properties are set before we determine that a message is empty. // properties are set before we determine that a message is empty.
if (message.isEmpty()) { if (message.isEmpty()) {
log.info( log.info(`${idLog}: Dropping empty message`);
`handleDataMessage: Dropping empty message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
);
confirm(); confirm();
return; return;
} }
@ -2650,7 +2640,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
log.info('Incoming expirationTimerUpdate changed timer', { log.info('Incoming expirationTimerUpdate changed timer', {
id: conversation.idForLogging(), id: conversation.idForLogging(),
expireTimer: dataMessage.expireTimer || 'disabled', expireTimer: dataMessage.expireTimer || 'disabled',
source: 'handleDataMessage/expirationTimerUpdate', source: idLog,
}); });
conversation.set({ conversation.set({
expireTimer: dataMessage.expireTimer, expireTimer: dataMessage.expireTimer,
@ -2668,7 +2658,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
receivedAtMS: message.get('received_at_ms'), receivedAtMS: message.get('received_at_ms'),
sentAt: message.get('sent_at'), sentAt: message.get('sent_at'),
fromGroupUpdate: isGroupUpdate(message.attributes), fromGroupUpdate: isGroupUpdate(message.attributes),
reason: `handleDataMessage(${this.idForLogging()})`, reason: idLog,
}); });
} else if ( } else if (
// We won't turn off timers for these kinds of messages: // We won't turn off timers for these kinds of messages:
@ -2680,7 +2670,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
receivedAt: message.get('received_at'), receivedAt: message.get('received_at'),
receivedAtMS: message.get('received_at_ms'), receivedAtMS: message.get('received_at_ms'),
sentAt: message.get('sent_at'), sentAt: message.get('sent_at'),
reason: `handleDataMessage(${this.idForLogging()})`, reason: idLog,
}); });
} }
} }
@ -2714,7 +2704,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
!message.isValidTapToView() !message.isValidTapToView()
) { ) {
log.warn( log.warn(
`Received tap to view message ${message.idForLogging()} with invalid data. Erasing contents.` `${idLog}: Received tap to view message with invalid data. Erasing contents.`
); );
message.set({ message.set({
isTapToViewInvalid: true, isTapToViewInvalid: true,
@ -2759,7 +2749,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
); );
const { messaging } = window.textsecure; const { messaging } = window.textsecure;
if (!messaging) { if (!messaging) {
throw new Error('handleDataMessage: messaging is not available'); throw new Error(`${idLog}: messaging is not available`);
} }
const response = await messaging.server.getBoostBadgesFromServer( const response = await messaging.server.getBoostBadgesFromServer(
userLanguages userLanguages
@ -2771,7 +2761,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const badge = boostBadgesByLevel[level]; const badge = boostBadgesByLevel[level];
if (!badge) { if (!badge) {
log.error( log.error(
`handleDataMessage: gift badge with level ${level} not found on server` `${idLog}: gift badge with level ${level} not found on server`
); );
} else { } else {
await window.reduxActions.badges.updateOrCreate([badge]); await window.reduxActions.badges.updateOrCreate([badge]);
@ -2806,7 +2796,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (window.attachmentDownloadQueue) { if (window.attachmentDownloadQueue) {
window.attachmentDownloadQueue.unshift(message); window.attachmentDownloadQueue.unshift(message);
log.info( log.info(
'Adding to attachmentDownloadQueue', `${idLog}: Adding to attachmentDownloadQueue`,
message.get('sent_at') message.get('sent_at')
); );
} else { } else {
@ -2817,19 +2807,11 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const isFirstRun = true; const isFirstRun = true;
await this.modifyTargetMessage(conversation, isFirstRun); await this.modifyTargetMessage(conversation, isFirstRun);
log.info( log.info(`${idLog}: Batching save`);
'handleDataMessage: Batching save for',
message.get('sent_at')
);
this.saveAndNotify(conversation, confirm); this.saveAndNotify(conversation, confirm);
} catch (error) { } catch (error) {
const errorForLog = error && error.stack ? error.stack : error; const errorForLog = error && error.stack ? error.stack : error;
log.error( log.error(`${idLog}: error:`, errorForLog);
'handleDataMessage',
message.idForLogging(),
'error:',
errorForLog
);
throw error; throw error;
} }
}); });

View File

@ -281,21 +281,21 @@ export class EmojiCompletion {
range.collapse(true); range.collapse(true);
// if we can, position the popper at the beginning of the emoji text (:word) // if we can, position the popper at the beginning of the emoji text (:word)
const endContainerTextContent = range.endContainer.textContent; const textBeforeCursor = range.endContainer.textContent?.slice(
const startOfEmojiText = endContainerTextContent?.lastIndexOf(':'); 0,
range.startOffset
);
const startOfEmojiText = textBeforeCursor?.lastIndexOf(':');
if ( if (
endContainerTextContent && textBeforeCursor &&
isNumber(startOfEmojiText) && isNumber(startOfEmojiText) &&
startOfEmojiText !== -1 startOfEmojiText !== -1
) { ) {
range.setStart( range.setStart(range.endContainer, startOfEmojiText);
range.endContainer,
range.endOffset -
(endContainerTextContent.length - startOfEmojiText)
);
} else { } else {
log.warn( log.warn(
`Could not find the beginning of the emoji word to be completed. startOfEmojiText=${startOfEmojiText}, endContainerTextContent.length=${endContainerTextContent?.length}, range.offsets=${range.startOffset}-${range.endOffset}` `Could not find the beginning of the emoji word to be completed. startOfEmojiText=${startOfEmojiText}, textBeforeCursor.length=${textBeforeCursor?.length}, range.offsets=${range.startOffset}-${range.endOffset}`
); );
} }
return range.getClientRects()[0]; return range.getClientRects()[0];

View File

@ -28,7 +28,8 @@ export function setIsInitialSync(newValue: boolean): void {
async function updateConversationFromContactSync( async function updateConversationFromContactSync(
conversation: ConversationModel, conversation: ConversationModel,
details: ModifiedContactDetails, details: ModifiedContactDetails,
receivedAtCounter: number receivedAtCounter: number,
sentAt: number
): Promise<void> { ): Promise<void> {
const { writeNewAttachmentData, deleteAttachmentData, doesAttachmentExist } = const { writeNewAttachmentData, deleteAttachmentData, doesAttachmentExist } =
window.Signal.Migrations; window.Signal.Migrations;
@ -67,7 +68,7 @@ async function updateConversationFromContactSync(
receivedAt: receivedAtCounter, receivedAt: receivedAtCounter,
fromSync: true, fromSync: true,
isInitialSync, isInitialSync,
reason: 'contact sync', reason: `contact sync (sent=${sentAt})`,
}); });
window.Whisper.events.trigger('incrementProgress'); window.Whisper.events.trigger('incrementProgress');
@ -79,6 +80,7 @@ async function doContactSync({
contacts, contacts,
complete, complete,
receivedAtCounter, receivedAtCounter,
sentAt,
}: ContactSyncEvent): Promise<void> { }: ContactSyncEvent): Promise<void> {
// iOS sets `syncMessage.contacts.complete` flag to `true` unconditionally // iOS sets `syncMessage.contacts.complete` flag to `true` unconditionally
// and so we have to employ tricks to figure out whether the sync is full or // and so we have to employ tricks to figure out whether the sync is full or
@ -93,7 +95,7 @@ async function doContactSync({
window.storage.user.getUuid()?.toString() window.storage.user.getUuid()?.toString()
); );
const logId = `doContactSync(${receivedAtCounter}, isFullSync=${isFullSync})`; const logId = `doContactSync(sent=${sentAt}, receivedAt=${receivedAtCounter}, isFullSync=${isFullSync})`;
log.info(`${logId}: got ${contacts.length} contacts`); log.info(`${logId}: got ${contacts.length} contacts`);
const updatedConversations = new Set<ConversationModel>(); const updatedConversations = new Set<ConversationModel>();
@ -130,7 +132,8 @@ async function doContactSync({
await updateConversationFromContactSync( await updateConversationFromContactSync(
conversation, conversation,
details, details,
receivedAtCounter receivedAtCounter,
sentAt
); );
updatedConversations.add(conversation); updatedConversations.add(conversation);
@ -187,6 +190,8 @@ async function doContactSync({
} }
export async function onContactSync(ev: ContactSyncEvent): Promise<void> { export async function onContactSync(ev: ContactSyncEvent): Promise<void> {
log.info(`onContactSync(${ev.receivedAtCounter}): queueing sync`); log.info(
`onContactSync(sent=${ev.sentAt}, receivedAt=${ev.receivedAtCounter}): queueing sync`
);
await queue.add(() => doContactSync(ev)); await queue.add(() => doContactSync(ev));
} }

View File

@ -3071,7 +3071,8 @@ export default class MessageReceiver
const contactSync = new ContactSyncEvent( const contactSync = new ContactSyncEvent(
Array.from(contactBuffer), Array.from(contactBuffer),
Boolean(contacts.complete), Boolean(contacts.complete),
envelope.receivedAtCounter envelope.receivedAtCounter,
envelope.timestamp
); );
await this.dispatchAndWait(contactSync); await this.dispatchAndWait(contactSync);

View File

@ -77,7 +77,8 @@ export class ContactSyncEvent extends Event {
constructor( constructor(
public readonly contacts: ReadonlyArray<ModifiedContactDetails>, public readonly contacts: ReadonlyArray<ModifiedContactDetails>,
public readonly complete: boolean, public readonly complete: boolean,
public readonly receivedAtCounter: number public readonly receivedAtCounter: number,
public readonly sentAt: number
) { ) {
super('contactSync'); super('contactSync');
} }

View File

@ -7,6 +7,7 @@ import type { UUIDStringType } from '../types/UUID';
import * as log from '../logging/log'; import * as log from '../logging/log';
import { isEnabled } from '../RemoteConfig'; import { isEnabled } from '../RemoteConfig';
import { isDirectConversation, isMe } from './whatTypeOfConversation'; import { isDirectConversation, isMe } from './whatTypeOfConversation';
import { isBeta } from './version';
export async function getUuidsForE164s( export async function getUuidsForE164s(
server: Pick<WebAPIType, 'cdsLookup'>, server: Pick<WebAPIType, 'cdsLookup'>,
@ -39,7 +40,10 @@ export async function getUuidsForE164s(
} }
const returnAcisWithoutUaks = isEnabled('desktop.cdsi.returnAcisWithoutUaks'); const returnAcisWithoutUaks = isEnabled('desktop.cdsi.returnAcisWithoutUaks');
const isCDSI = isEnabled('desktop.cdsi'); const isCDSI =
isEnabled('desktop.cdsi') ||
(isBeta(window.getVersion()) && isEnabled('desktop.cdsi.beta'));
const isMirroring = isEnabled('desktop.cdsi.mirroring'); const isMirroring = isEnabled('desktop.cdsi.mirroring');
log.info( log.info(

View File

@ -7233,10 +7233,10 @@ electron-window@^0.8.0:
dependencies: dependencies:
is-electron-renderer "^2.0.0" is-electron-renderer "^2.0.0"
electron@20.1.0: electron@20.1.3:
version "20.1.0" version "20.1.3"
resolved "https://registry.yarnpkg.com/electron/-/electron-20.1.0.tgz#2de079adc551dadc21f11d12a37c70873b9ffb40" resolved "https://registry.yarnpkg.com/electron/-/electron-20.1.3.tgz#8a4e3f6945fa7ed06ba54d0f987737b0e057ceb4"
integrity sha512-gzl6fdZe5g0qmzCC6Ejxa1Oa8eqUSxs4+QLtrM7SyEVp+mEPJAOoDe0xD8ayRQqeXTBxLK1LFrKtc4c98iufsg== integrity sha512-DXBHzAwcpCor9MrxG9QA3Zt0sNcQbJ8ZJCYTC6xpuPe5wugBa6RF3hXqDUYdD2yOCUhjLbD3VASWn0+5LdYT3g==
dependencies: dependencies:
"@electron/get" "^1.14.1" "@electron/get" "^1.14.1"
"@types/node" "^16.11.26" "@types/node" "^16.11.26"