From 9d9a41b263a12da7b456c8f85224c6defdd3fd8a Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 13 May 2019 18:00:52 +0100 Subject: [PATCH 01/16] Save `content.info` as a local for readability --- src/components/views/messages/MImageBody.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 9fd42fb31d7..cb12259c9b2 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -198,9 +198,11 @@ export default class MImageBody extends React.Component { // so we'll need to download the original image for this to work // well for now. First, let's try a few cases that let us avoid // downloading the original: - if (pixelRatio === 1.0 || - (!content.info || !content.info.w || - !content.info.h || !content.info.size)) { + const info = content.info; + if ( + pixelRatio === 1.0 || + (!info || !info.w || !info.h || !info.size) + ) { // always thumbnail. it may look a bit worse, but it'll save bandwidth. // which is probably desirable on a lo-dpi device anyway. return this.context.matrixClient.mxcUrlToHttp(content.url, thumbWidth, thumbHeight); @@ -215,10 +217,10 @@ export default class MImageBody extends React.Component { // timeline (e.g. >1MB). const isLargerThanThumbnail = ( - content.info.w > thumbWidth || - content.info.h > thumbHeight + info.w > thumbWidth || + info.h > thumbHeight ); - const isLargeFileSize = content.info.size > 1*1024*1024; + const isLargeFileSize = info.size > 1*1024*1024; if (isLargeFileSize && isLargerThanThumbnail) { // image is too large physically and bytewise to clutter our timeline so From 7881369b985119866737f50d64b4f622c2bdcabf Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 13 May 2019 18:28:57 +0100 Subject: [PATCH 02/16] Always thumbnail for GIFs When displaying a GIF, we always want to thumbnail so that we can properly respect the user's GIF autoplay setting (which relies on thumbnailing to produce the static preview image). Fixes https://github.com/vector-im/riot-web/issues/9658 --- src/components/views/messages/MImageBody.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index cb12259c9b2..4b5e1c20fae 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -200,6 +200,7 @@ export default class MImageBody extends React.Component { // downloading the original: const info = content.info; if ( + this._isGif() || pixelRatio === 1.0 || (!info || !info.w || !info.h || !info.size) ) { From 1584ab42c27cb95e1b142d811c47233348c8db0e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 May 2019 14:12:58 -0600 Subject: [PATCH 03/16] Support a backup room ID in PermalinkCreator In the case of room upgrades, it is possible the client is trying to render the room create event, but the user has never been in the old room. This results in an error because the PermalinkCreator cannot possibly figure out a room ID. Instead, we'll feed the creator an alternate room ID to try if the room object can't be provided. Fixes https://github.com/vector-im/riot-web/issues/9636 --- src/components/views/messages/RoomCreate.js | 2 +- src/matrix-to.js | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/views/messages/RoomCreate.js b/src/components/views/messages/RoomCreate.js index f9dc3df2dca..95254323fab 100644 --- a/src/components/views/messages/RoomCreate.js +++ b/src/components/views/messages/RoomCreate.js @@ -49,7 +49,7 @@ module.exports = React.createClass({ return
; // We should never have been instaniated in this case } const prevRoom = MatrixClientPeg.get().getRoom(predecessor['room_id']); - const permalinkCreator = new RoomPermalinkCreator(prevRoom); + const permalinkCreator = new RoomPermalinkCreator(prevRoom, predecessor['room_id']); permalinkCreator.load(); const predecessorPermalink = permalinkCreator.forEvent(predecessor['event_id']); return
diff --git a/src/matrix-to.js b/src/matrix-to.js index a198bb422ee..14467cb4c5e 100644 --- a/src/matrix-to.js +++ b/src/matrix-to.js @@ -70,8 +70,12 @@ const MAX_SERVER_CANDIDATES = 3; // the list and magically have the link work. export class RoomPermalinkCreator { - constructor(room) { + // We support being given a roomId as a fallback in the event the `room` object + // doesn't exist or is not healthy for us to rely on. For example, loading a + // permalink to a room which the MatrixClient doesn't know about. + constructor(room, roomId=null) { this._room = room; + this._roomId = room ? room.roomId : roomId; this._highestPlUserId = null; this._populationMap = null; this._bannedHostsRegexps = null; @@ -79,6 +83,10 @@ export class RoomPermalinkCreator { this._serverCandidates = null; this._started = false; + if (!this._roomId) { + throw new Error("Failed to resolve a roomId for the permalink creator to use"); + } + this.onMembership = this.onMembership.bind(this); this.onRoomState = this.onRoomState.bind(this); } @@ -116,13 +124,13 @@ export class RoomPermalinkCreator { } forEvent(eventId) { - const roomId = this._room.roomId; + const roomId = this._roomId; const permalinkBase = `${baseUrl}/#/${roomId}/${eventId}`; return `${permalinkBase}${encodeServerCandidates(this._serverCandidates)}`; } forRoom() { - const roomId = this._room.roomId; + const roomId = this._roomId; const permalinkBase = `${baseUrl}/#/${roomId}`; return `${permalinkBase}${encodeServerCandidates(this._serverCandidates)}`; } @@ -246,7 +254,6 @@ export class RoomPermalinkCreator { } } - export function makeUserPermalink(userId) { return `${baseUrl}/#/${userId}`; } From f86ccae4a0f3c6b5ade3ea861f1b07d2c2484ce7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 May 2019 14:31:40 -0600 Subject: [PATCH 04/16] Give all the matrix.to tests a room ID to abuse --- test/matrix-to-test.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/matrix-to-test.js b/test/matrix-to-test.js index 45b5f74c5e3..33947703ef0 100644 --- a/test/matrix-to-test.js +++ b/test/matrix-to-test.js @@ -74,7 +74,7 @@ describe('matrix-to', function() { }); it('should pick no candidate servers when the room has no members', function() { - const room = mockRoom(null, []); + const room = mockRoom("!fake:example.org", []); const creator = new RoomPermalinkCreator(room); creator.load(); expect(creator._serverCandidates).toBeTruthy(); @@ -82,7 +82,7 @@ describe('matrix-to', function() { }); it('should pick a candidate server for the highest power level user in the room', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:pl_50", powerLevel: 50, @@ -109,7 +109,7 @@ describe('matrix-to', function() { userId: "@alice:pl_95", powerLevel: 95, }; - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:pl_50", powerLevel: 50, @@ -132,7 +132,7 @@ describe('matrix-to', function() { }); it('should pick candidate servers based on user population', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:first", powerLevel: 0, @@ -168,7 +168,7 @@ describe('matrix-to', function() { }); it('should pick prefer candidate servers with higher power levels', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:first", powerLevel: 100, @@ -195,7 +195,7 @@ describe('matrix-to', function() { }); it('should pick a maximum of 3 candidate servers', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:alpha", powerLevel: 100, @@ -224,7 +224,7 @@ describe('matrix-to', function() { }); it('should not consider IPv4 hosts', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:127.0.0.1", powerLevel: 100, @@ -237,7 +237,7 @@ describe('matrix-to', function() { }); it('should not consider IPv6 hosts', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:[::1]", powerLevel: 100, @@ -250,7 +250,7 @@ describe('matrix-to', function() { }); it('should not consider IPv4 hostnames with ports', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:127.0.0.1:8448", powerLevel: 100, @@ -263,7 +263,7 @@ describe('matrix-to', function() { }); it('should not consider IPv6 hostnames with ports', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:[::1]:8448", powerLevel: 100, @@ -276,7 +276,7 @@ describe('matrix-to', function() { }); it('should work with hostnames with ports', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:example.org:8448", powerLevel: 100, @@ -291,7 +291,7 @@ describe('matrix-to', function() { }); it('should not consider servers explicitly denied by ACLs', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:evilcorp.com", powerLevel: 100, @@ -311,7 +311,7 @@ describe('matrix-to', function() { }); it('should not consider servers not allowed by ACLs', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:evilcorp.com", powerLevel: 100, @@ -331,7 +331,7 @@ describe('matrix-to', function() { }); it('should consider servers not explicitly banned by ACLs', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:evilcorp.com", powerLevel: 100, @@ -352,7 +352,7 @@ describe('matrix-to', function() { }); it('should consider servers not disallowed by ACLs', function() { - const room = mockRoom(null, [ + const room = mockRoom("!fake:example.org", [ { userId: "@alice:evilcorp.com", powerLevel: 100, From a0ecd89c94a4269d81ff2b163a82b9f767e94769 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 11:44:00 +0100 Subject: [PATCH 05/16] Fix email registration: pt. 1 We look to see if there's already a user logged in and if there is, restore that session instead of logging the user in as their new account. We still set this 'is_registered' flag though, even though in that case it's not a newly registered account that's being restored, so don't set in that case. --- src/components/structures/MatrixChat.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 277985ba1d0..49ee1ca8726 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1710,9 +1710,6 @@ export default React.createClass({ // returns a promise which resolves to the new MatrixClient onRegistered: function(credentials) { - // XXX: This should be in state or ideally store(s) because we risk not - // rendering the most up-to-date view of state otherwise. - this._is_registered = true; if (this.state.register_session_id) { // The user came in through an email validation link. To avoid overwriting // their session, check to make sure the session isn't someone else. @@ -1748,6 +1745,9 @@ export default React.createClass({ return MatrixClientPeg.get(); } } + // XXX: This should be in state or ideally store(s) because we risk not + // rendering the most up-to-date view of state otherwise. + this._is_registered = true; return Lifecycle.setLoggedIn(credentials); }, From c11d26d809ef42b37973db874f9408fd78a19479 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 11:59:38 +0100 Subject: [PATCH 06/16] Fix email registration, pt. 2 Regressed in https://github.com/matrix-org/matrix-react-sdk/pull/2768 where we check for an existing stored account first and restore that instead if it exist, telling the user. We usually make a guest account when the user first hits the page though, so this just restored this guest account. Don't restore the account if it's just a guest account (which, as per comment, is not perfect, but is definitely better than the current behaviour). Fixes https://github.com/vector-im/riot-web/issues/9581 --- src/Lifecycle.js | 29 ++++++++++++++++--------- src/components/structures/MatrixChat.js | 8 +++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 527394da4db..ca4c7c48f8e 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -126,6 +126,15 @@ export function getStoredSessionOwner() { return hsUrl && userId && accessToken ? userId : null; } +/** + * @returns {bool} True if the stored session is for a guest user or false if it is + * for a real user. If there is no stored session, return null. + */ +export function getStoredSessionIsGuest() { + const {hsUrl, isUrl, accessToken, userId, deviceId, isGuest} = _getLocalStorageSessionVars(); + return hsUrl && userId && accessToken ? isGuest : null; +} + /** * @param {Object} queryParams string->string map of the * query-parameters extracted from the real query-string of the starting @@ -235,7 +244,15 @@ function _getLocalStorageSessionVars() { const userId = localStorage.getItem("mx_user_id"); const deviceId = localStorage.getItem("mx_device_id"); - return {hsUrl, isUrl, accessToken, userId, deviceId}; + let isGuest; + if (localStorage.getItem("mx_is_guest") !== null) { + isGuest = localStorage.getItem("mx_is_guest") === "true"; + } else { + // legacy key name + isGuest = localStorage.getItem("matrix-is-guest") === "true"; + } + + return {hsUrl, isUrl, accessToken, userId, deviceId, isGuest}; } // returns a promise which resolves to true if a session is found in @@ -253,15 +270,7 @@ async function _restoreFromLocalStorage() { return false; } - const {hsUrl, isUrl, accessToken, userId, deviceId} = _getLocalStorageSessionVars(); - - let isGuest; - if (localStorage.getItem("mx_is_guest") !== null) { - isGuest = localStorage.getItem("mx_is_guest") === "true"; - } else { - // legacy key name - isGuest = localStorage.getItem("matrix-is-guest") === "true"; - } + const {hsUrl, isUrl, accessToken, userId, deviceId, isGuest} = _getLocalStorageSessionVars(); if (accessToken && userId && hsUrl) { console.log(`Restoring session for ${userId}`); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 49ee1ca8726..0b52cfa1bcb 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1712,9 +1712,13 @@ export default React.createClass({ onRegistered: function(credentials) { if (this.state.register_session_id) { // The user came in through an email validation link. To avoid overwriting - // their session, check to make sure the session isn't someone else. + // their session, check to make sure the session isn't someone else, and + // isn't a guest user since we'll usually have set a guest user session before + // starting the registration process. This isn't perfect since it's possible + // the user had a separate guest session they didn't actually mean to replace. const sessionOwner = Lifecycle.getStoredSessionOwner(); - if (sessionOwner && sessionOwner !== credentials.userId) { + const sessionIsGuest = Lifecycle.getStoredSessionIsGuest(); + if (sessionOwner && !sessionIsGuest && sessionOwner !== credentials.userId) { console.log( `Found a session for ${sessionOwner} but ${credentials.userId} is trying to verify their ` + `email address. Restoring the session for ${sessionOwner} with warning.`, From 7ac82a23ab62eb01118e885c011dae907e4034de Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 12:11:07 +0100 Subject: [PATCH 07/16] Yes yes, eslint --- src/Lifecycle.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index ca4c7c48f8e..0e2389fd1c1 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -131,8 +131,8 @@ export function getStoredSessionOwner() { * for a real user. If there is no stored session, return null. */ export function getStoredSessionIsGuest() { - const {hsUrl, isUrl, accessToken, userId, deviceId, isGuest} = _getLocalStorageSessionVars(); - return hsUrl && userId && accessToken ? isGuest : null; + const sessVars = _getLocalStorageSessionVars(); + return sessVars.hsUrl && sessVars.userId && sessVars.accessToken ? sessVars.isGuest : null; } /** From d613498b8a3ec65ea51d0794a3b6b29e604ad126 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 13 May 2019 14:17:09 +0100 Subject: [PATCH 08/16] Fix bug where email was not required where it shouldn't have been See comment! Fixes https://github.com/vector-im/riot-web/issues/9681 --- src/components/views/auth/RegistrationForm.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index 7c083ea2700..bef0b9e0195 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd +Copyright 2018, 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -150,7 +150,11 @@ module.exports = React.createClass({ if (!field) { continue; } - field.validate({ allowEmpty: false }); + // We must wait for these validations to finish before queueing + // up the setState below so our setState gies in the queue after + // all the setStates from these validate calls (that's how we + // know they've finished). + await field.validate({ allowEmpty: false }); } // Validation and state updates are async, so we need to wait for them to complete From 2d6a313871562733040805de630abe6547d5c576 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 13 May 2019 14:24:56 +0100 Subject: [PATCH 09/16] Typo Co-Authored-By: J. Ryan Stinnett --- src/components/views/auth/RegistrationForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index bef0b9e0195..654387e196d 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -151,7 +151,7 @@ module.exports = React.createClass({ continue; } // We must wait for these validations to finish before queueing - // up the setState below so our setState gies in the queue after + // up the setState below so our setState goes in the queue after // all the setStates from these validate calls (that's how we // know they've finished). await field.validate({ allowEmpty: false }); From b6fd485dadae9202277c67402c78afdd7994b50d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 11:44:00 +0100 Subject: [PATCH 10/16] Fix email registration: pt. 1 We look to see if there's already a user logged in and if there is, restore that session instead of logging the user in as their new account. We still set this 'is_registered' flag though, even though in that case it's not a newly registered account that's being restored, so don't set in that case. --- src/components/structures/MatrixChat.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 33f1bac090b..c0107263fc2 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1733,9 +1733,6 @@ export default React.createClass({ // returns a promise which resolves to the new MatrixClient onRegistered: function(credentials) { - // XXX: This should be in state or ideally store(s) because we risk not - // rendering the most up-to-date view of state otherwise. - this._is_registered = true; if (this.state.register_session_id) { // The user came in through an email validation link. To avoid overwriting // their session, check to make sure the session isn't someone else. @@ -1771,6 +1768,9 @@ export default React.createClass({ return MatrixClientPeg.get(); } } + // XXX: This should be in state or ideally store(s) because we risk not + // rendering the most up-to-date view of state otherwise. + this._is_registered = true; return Lifecycle.setLoggedIn(credentials); }, From 040424f462d523b00bfe6c19964fd261d1633743 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 11:59:38 +0100 Subject: [PATCH 11/16] Fix email registration, pt. 2 Regressed in https://github.com/matrix-org/matrix-react-sdk/pull/2768 where we check for an existing stored account first and restore that instead if it exist, telling the user. We usually make a guest account when the user first hits the page though, so this just restored this guest account. Don't restore the account if it's just a guest account (which, as per comment, is not perfect, but is definitely better than the current behaviour). Fixes https://github.com/vector-im/riot-web/issues/9581 --- src/Lifecycle.js | 29 ++++++++++++++++--------- src/components/structures/MatrixChat.js | 8 +++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 527394da4db..ca4c7c48f8e 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -126,6 +126,15 @@ export function getStoredSessionOwner() { return hsUrl && userId && accessToken ? userId : null; } +/** + * @returns {bool} True if the stored session is for a guest user or false if it is + * for a real user. If there is no stored session, return null. + */ +export function getStoredSessionIsGuest() { + const {hsUrl, isUrl, accessToken, userId, deviceId, isGuest} = _getLocalStorageSessionVars(); + return hsUrl && userId && accessToken ? isGuest : null; +} + /** * @param {Object} queryParams string->string map of the * query-parameters extracted from the real query-string of the starting @@ -235,7 +244,15 @@ function _getLocalStorageSessionVars() { const userId = localStorage.getItem("mx_user_id"); const deviceId = localStorage.getItem("mx_device_id"); - return {hsUrl, isUrl, accessToken, userId, deviceId}; + let isGuest; + if (localStorage.getItem("mx_is_guest") !== null) { + isGuest = localStorage.getItem("mx_is_guest") === "true"; + } else { + // legacy key name + isGuest = localStorage.getItem("matrix-is-guest") === "true"; + } + + return {hsUrl, isUrl, accessToken, userId, deviceId, isGuest}; } // returns a promise which resolves to true if a session is found in @@ -253,15 +270,7 @@ async function _restoreFromLocalStorage() { return false; } - const {hsUrl, isUrl, accessToken, userId, deviceId} = _getLocalStorageSessionVars(); - - let isGuest; - if (localStorage.getItem("mx_is_guest") !== null) { - isGuest = localStorage.getItem("mx_is_guest") === "true"; - } else { - // legacy key name - isGuest = localStorage.getItem("matrix-is-guest") === "true"; - } + const {hsUrl, isUrl, accessToken, userId, deviceId, isGuest} = _getLocalStorageSessionVars(); if (accessToken && userId && hsUrl) { console.log(`Restoring session for ${userId}`); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index c0107263fc2..b1001e3b833 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1735,9 +1735,13 @@ export default React.createClass({ onRegistered: function(credentials) { if (this.state.register_session_id) { // The user came in through an email validation link. To avoid overwriting - // their session, check to make sure the session isn't someone else. + // their session, check to make sure the session isn't someone else, and + // isn't a guest user since we'll usually have set a guest user session before + // starting the registration process. This isn't perfect since it's possible + // the user had a separate guest session they didn't actually mean to replace. const sessionOwner = Lifecycle.getStoredSessionOwner(); - if (sessionOwner && sessionOwner !== credentials.userId) { + const sessionIsGuest = Lifecycle.getStoredSessionIsGuest(); + if (sessionOwner && !sessionIsGuest && sessionOwner !== credentials.userId) { console.log( `Found a session for ${sessionOwner} but ${credentials.userId} is trying to verify their ` + `email address. Restoring the session for ${sessionOwner} with warning.`, From 4aec75ef699198a4c13bf8f21fec7d7b8815e0f6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 12:11:07 +0100 Subject: [PATCH 12/16] Yes yes, eslint --- src/Lifecycle.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index ca4c7c48f8e..0e2389fd1c1 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -131,8 +131,8 @@ export function getStoredSessionOwner() { * for a real user. If there is no stored session, return null. */ export function getStoredSessionIsGuest() { - const {hsUrl, isUrl, accessToken, userId, deviceId, isGuest} = _getLocalStorageSessionVars(); - return hsUrl && userId && accessToken ? isGuest : null; + const sessVars = _getLocalStorageSessionVars(); + return sessVars.hsUrl && sessVars.userId && sessVars.accessToken ? sessVars.isGuest : null; } /** From 4e2cce7d44af8528138b779478fa6b4ee1756e86 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 13:48:46 +0100 Subject: [PATCH 13/16] Prepare changelog for v1.1.1 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d9a01e6684..988a85fd433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +Changes in [1.1.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.1.1) (2019-05-14) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.1.0...v1.1.1) + + * Fix registration with email + [\#2970](https://github.com/matrix-org/matrix-react-sdk/pull/2970) + * Fix bug where email was not required where it shouldn't have been + [\#2969](https://github.com/matrix-org/matrix-react-sdk/pull/2969) + Changes in [1.1.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.1.0) (2019-05-07) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.1.0-rc.1...v1.1.0) From 851d2076113d1aff90c14ebc13a645b003dbbe9e Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 13:48:47 +0100 Subject: [PATCH 14/16] v1.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5735fed77cc..df51ac65261 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.1.0", + "version": "1.1.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From f19e70c219ecd8b3c7d07ffa394ef6333f79a7dc Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 14 May 2019 13:55:38 +0100 Subject: [PATCH 15/16] Add comment about thumbnailing for GIFs --- src/components/views/messages/MImageBody.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 4b5e1c20fae..2f120221401 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -197,15 +197,18 @@ export default class MImageBody extends React.Component { // synapse only supports 800x600 thumbnails for now though, // so we'll need to download the original image for this to work // well for now. First, let's try a few cases that let us avoid - // downloading the original: + // downloading the original, including: + // - When displaying a GIF, we always want to thumbnail so that we can + // properly respect the user's GIF autoplay setting (which relies on + // thumbnailing to produce the static preview image) + // - On a low DPI device, always thumbnail to save bandwidth + // - If there's no sizing info in the event, default to thumbnail const info = content.info; if ( this._isGif() || pixelRatio === 1.0 || (!info || !info.w || !info.h || !info.size) ) { - // always thumbnail. it may look a bit worse, but it'll save bandwidth. - // which is probably desirable on a lo-dpi device anyway. return this.context.matrixClient.mxcUrlToHttp(content.url, thumbWidth, thumbHeight); } else { // we should only request thumbnails if the image is bigger than 800x600 From a2e0dc2f7e321eb2b47ca72f4aa0e47a216e379f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 14 May 2019 16:51:50 +0100 Subject: [PATCH 16/16] Tweak message action bar position This moves the message action bar up slightly to avoid covering message text. --- res/css/views/messages/_MessageActionBar.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/messages/_MessageActionBar.scss b/res/css/views/messages/_MessageActionBar.scss index 419542036ed..e66c99e95b4 100644 --- a/res/css/views/messages/_MessageActionBar.scss +++ b/res/css/views/messages/_MessageActionBar.scss @@ -23,7 +23,7 @@ limitations under the License. line-height: 24px; border-radius: 4px; background: $message-action-bar-bg-color; - top: -13px; + top: -18px; right: 8px; user-select: none;