Bugfixes for v1.29

* If focus was set to document.body during archive, focus left pane
* Shortcut Guide: Add space between text and shortcut highlight
* Ensure that draft attachment can be closed with click on X button
* Move to keyDown event for user idle checking
* Additional resiliency around avatars; check for them on on-disk
* Increase timeouts to preserve websocket connection
* On startup, be resilient to malformed JSON in log files
* Don't crash if shell.openExternal returns an error
* Whenever we request a contact/group sync, also request block list
* Avatar popup: Ensure styling is mouse- and keyboard-appropriate
* MainHeader: Create popperRoot on demand, not on mount
* CompositionInput: Disable default Ctrl-/ shortcut
* Update libphonenumber
This commit is contained in:
Scott Nonnenberg 2019-12-03 12:02:50 -08:00 committed by Ken Powers
parent ee9e86ab7a
commit e9f08c3da9
19 changed files with 300 additions and 128 deletions

View file

@ -76,7 +76,7 @@
const ACTIVE_TIMEOUT = 15 * 1000;
const ACTIVE_EVENTS = [
'click',
'keypress',
'keydown',
'mousedown',
'mousemove',
// 'scroll', // this is triggered by Timeline re-renders, can't use
@ -193,6 +193,7 @@
upgradeMessageSchema,
writeNewAttachmentData,
deleteAttachmentData,
doesAttachmentExist,
} = window.Signal.Migrations;
const { Views } = window.Signal;
@ -1049,6 +1050,23 @@
document.body
);
// It's very likely that the act of archiving a conversation will set focus to
// 'none,' or the top-level body element. This resets it to the left pane,
// whether in the normal conversation list or search results.
if (document.activeElement === document.body) {
const leftPaneEl = document.querySelector('.module-left-pane__list');
if (leftPaneEl) {
leftPaneEl.focus();
}
const searchResultsEl = document.querySelector(
'.module-search-results'
);
if (searchResultsEl) {
searchResultsEl.focus();
}
}
event.preventDefault();
event.stopPropagation();
return;
@ -1852,12 +1870,14 @@
{
writeNewAttachmentData,
deleteAttachmentData,
doesAttachmentExist,
}
);
conversation.set(newAttributes);
}
window.Signal.Data.updateConversation(id, conversation.attributes);
const { expireTimer } = details;
const isValidExpireTimer = typeof expireTimer === 'number';
if (isValidExpireTimer) {
@ -1934,6 +1954,7 @@
{
writeNewAttachmentData,
deleteAttachmentData,
doesAttachmentExist,
}
);
conversation.set(newAttributes);

View file

@ -30,6 +30,7 @@
const { Conversation, Contact, Message, PhoneNumber } = window.Signal.Types;
const {
deleteAttachmentData,
doesAttachmentExist,
getAbsoluteAttachmentPath,
loadAttachmentData,
readStickerData,
@ -1746,7 +1747,6 @@
error && error.stack ? error.stack : error
);
await c.dropProfileKey();
return;
}
try {
@ -1814,6 +1814,7 @@
{
writeNewAttachmentData,
deleteAttachmentData,
doesAttachmentExist,
}
);
this.set(newAttributes);

View file

@ -114,6 +114,7 @@ function initializeMigrations({
createReader,
createWriterForExisting,
createWriterForNew,
createDoesExist,
getDraftPath,
getPath,
getStickersPath,
@ -139,6 +140,7 @@ function initializeMigrations({
const copyIntoAttachmentsDirectory = Attachments.copyIntoAttachmentsDirectory(
attachmentsPath
);
const doesAttachmentExist = createDoesExist(attachmentsPath);
const stickersPath = getStickersPath(userDataPath);
const writeNewStickerData = createWriterForNew(stickersPath);
@ -173,6 +175,7 @@ function initializeMigrations({
}),
deleteSticker,
deleteTempFile,
doesAttachmentExist,
getAbsoluteAttachmentPath,
getAbsoluteDraftPath,
getAbsoluteStickerPath,

View file

@ -1,4 +1,4 @@
/* global crypto */
/* global crypto, window */
const { isFunction, isNumber } = require('lodash');
const { createLastMessageUpdate } = require('../../../ts/types/Conversation');
@ -16,17 +16,26 @@ function buildAvatarUpdater({ field }) {
}
const avatar = conversation[field];
const { writeNewAttachmentData, deleteAttachmentData } = options;
if (!isFunction(writeNewAttachmentData)) {
throw new Error(
'Conversation.buildAvatarUpdater: writeNewAttachmentData must be a function'
);
}
const {
deleteAttachmentData,
doesAttachmentExist,
writeNewAttachmentData,
} = options;
if (!isFunction(deleteAttachmentData)) {
throw new Error(
'Conversation.buildAvatarUpdater: deleteAttachmentData must be a function'
);
}
if (!isFunction(doesAttachmentExist)) {
throw new Error(
'Conversation.buildAvatarUpdater: deleteAttachmentData must be a function'
);
}
if (!isFunction(writeNewAttachmentData)) {
throw new Error(
'Conversation.buildAvatarUpdater: writeNewAttachmentData must be a function'
);
}
const newHash = await computeHash(data);
@ -41,8 +50,14 @@ function buildAvatarUpdater({ field }) {
}
const { hash, path } = avatar;
const exists = await doesAttachmentExist(path);
if (!exists) {
window.log.warn(
`Conversation.buildAvatarUpdater: attachment ${path} did not exist`
);
}
if (hash === newHash) {
if (exists && hash === newHash) {
return conversation;
}