From 6ed9a85dca27ff0793d2870c290f1128456e1f1b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 7 Jun 2017 15:34:07 +0100 Subject: [PATCH 01/13] Add API for POST /user_directory/search (#457) * Add API for POST /user_directory/search This takes a JSON body of the form: ```json { "term": "search term", "limit": 42, } ``` where "term" is the term to match against user IDs, display names and domains and "limit" is the maximum number of results to return (which is defaulted server-side). The response body looks like ```json { "results ": [ { "user_id": "@someid:mydomain.com", "display_name": "Some Name", "avatar_url": "mx://..." }, ... ], "limited": false } ``` where "limited" indicates whether the "limit" was used to truncate the list. --- src/base-apis.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/base-apis.js b/src/base-apis.js index 671ddcb01..35ef0938c 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -678,6 +678,31 @@ MatrixBaseApis.prototype.setRoomDirectoryVisibilityAppService = ); }; +// User Directory Operations +// ========================= + +/** + * Query the user directory with a term matching user IDs, display names and domains. + * @param {object} opts options + * @param {string} opts.term the term with which to search. + * @param {number} opts.limit the maximum number of results to return. The server will + * apply a limit if unspecified. + * @return {module:client.Promise} Resolves: an array of results. + */ +MatrixBaseApis.prototype.searchUserDirectory = function(opts) { + const body = { + search_term: opts.term, + }; + + if (opts.limit !== undefined) { + body.limit = opts.limit; + } + + return this._http.authedRequest( + undefined, "POST", "/user_directory/search", undefined, body, + ); +}; + // Media operations // ================ From 6cfcf92a286473a11e0139bf21ffe5aebdf9c6cc Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 9 Jun 2017 14:56:21 +0100 Subject: [PATCH 02/13] Make TimelineWindow.load resolve quicker if we have the events If we have the events in memory, let TimelineWindow.load() return a resolved promise, so that the UI can show the view straight away instead of showing the spinner. --- src/timeline-window.js | 51 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/timeline-window.js b/src/timeline-window.js index 523f8fcda..b68190cea 100644 --- a/src/timeline-window.js +++ b/src/timeline-window.js @@ -95,10 +95,30 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) { const self = this; initialWindowSize = initialWindowSize || 20; - // given an EventTimeline, and an event index within it, initialise our + // given an EventTimeline, find the event we were looking for, and initialise our // fields so that the event in question is in the middle of the window. - const initFields = function(timeline, eventIndex) { - const endIndex = Math.min(timeline.getEvents().length, + const initFields = function(timeline) { + let eventIndex; + + const events = timeline.getEvents(); + + if (!initialEventId) { + // we were looking for the live timeline: initialise to the end + eventIndex = events.length; + } else { + for (let i = 0; i < events.length; i++) { + if (events[i].getId() == initialEventId) { + eventIndex = i; + break; + } + } + + if (eventIndex === undefined) { + throw new Error("getEventTimeline result didn't include requested event"); + } + } + + const endIndex = Math.min(events.length, eventIndex + Math.ceil(initialWindowSize / 2)); const startIndex = Math.max(0, endIndex - initialWindowSize); self._start = new TimelineIndex(timeline, startIndex - timeline.getBaseIndex()); @@ -110,24 +130,19 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) { // we already have the data we need, which is important to keep room-switching // feeling snappy. // - // TODO: ideally we'd spot getEventTimeline returning a resolved promise and - // skip straight to the find-event loop. if (initialEventId) { - return this._client.getEventTimeline(this._timelineSet, initialEventId) - .then(function(tl) { - // make sure that our window includes the event - for (let i = 0; i < tl.getEvents().length; i++) { - if (tl.getEvents()[i].getId() == initialEventId) { - initFields(tl, i); - return; - } - } - throw new Error("getEventTimeline result didn't include requested event"); - }); + const prom = this._client.getEventTimeline(this._timelineSet, initialEventId); + + const promState = prom.inspect(); + if (promState.state == 'fulfilled') { + initFields(promState.value); + return q(); + } else { + return prom.then(initFields); + } } else { - // start with the most recent events const tl = this._timelineSet.getLiveTimeline(); - initFields(tl, tl.getEvents().length); + initFields(tl); return q(); } }; From 0c651623494c6ffed9117c4bb368e8ef8b3b0518 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Jun 2017 20:23:29 +0100 Subject: [PATCH 03/13] Prepare changelog for v0.7.11-rc.1 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f16b237f..4792a7cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +Changes in [0.7.11-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.11-rc.1) (2017-06-09) +============================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.10...v0.7.11-rc.1) + + * Make TimelineWindow.load resolve quicker if we have the events + [\#458](https://github.com/matrix-org/matrix-js-sdk/pull/458) + * Stop peeking when a matrix client is stopped + [\#451](https://github.com/matrix-org/matrix-js-sdk/pull/451) + * Update README: Clarify how to install libolm + [\#450](https://github.com/matrix-org/matrix-js-sdk/pull/450) + Changes in [0.7.10](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.10) (2017-06-02) ================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.9...v0.7.10) From bb5038b8b232c6f5fd2227e477b74d5054ca8e63 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Jun 2017 20:23:30 +0100 Subject: [PATCH 04/13] v0.7.11-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da27fa5a5..8b2d1444b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "0.7.10", + "version": "0.7.11-rc.1", "description": "Matrix Client-Server SDK for Javascript", "main": "index.js", "scripts": { From 96c1126fe550cf2977384e33d182d83391e94c27 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 12 Jun 2017 13:32:10 +0100 Subject: [PATCH 05/13] Add a bunch of logging around sending messages In an attempt to diagnose https://github.com/vector-im/riot-web/issues/4278, add some debug to make the rageshakes more useful. --- src/client.js | 9 ++++++++- src/crypto/DeviceList.js | 8 ++++++++ src/crypto/algorithms/megolm.js | 5 +++++ src/models/room.js | 2 ++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/client.js b/src/client.js index abd65eb9d..854b6ac2b 100644 --- a/src/client.js +++ b/src/client.js @@ -941,6 +941,8 @@ MatrixClient.prototype.sendEvent = function(roomId, eventType, content, txnId, txnId = this.makeTxnId(); } + console.log(`sendEvent of type ${eventType} in ${roomId} with txnId ${txnId}`); + // we always construct a MatrixEvent when sending because the store and // scheduler use them. We'll extract the params back out if it turns out // the client has no scheduler or store. @@ -1065,7 +1067,12 @@ function _sendEventHttpRequest(client, event) { return client._http.authedRequest( undefined, "PUT", path, undefined, event.getWireContent(), - ); + ).then((res) => { + console.log( + `Event sent to ${event.getRoomId()} with event id ${res.event_id}`, + ); + return res; + }); } /** diff --git a/src/crypto/DeviceList.js b/src/crypto/DeviceList.js index e3d55e318..2b608475b 100644 --- a/src/crypto/DeviceList.js +++ b/src/crypto/DeviceList.js @@ -76,6 +76,10 @@ export default class DeviceList { if (this._keyDownloadsInProgressByUser[u]) { // already a key download in progress/queued for this user; its results // will be good enough for us. + console.log( + `downloadKeys: already have a download in progress for ` + + `${u}: awaiting its result`, + ); promises.push(this._keyDownloadsInProgressByUser[u]); } else if (forceDownload || trackingStatus != TRACKING_STATUS_UP_TO_DATE) { usersToDownload.push(u); @@ -88,6 +92,10 @@ export default class DeviceList { promises.push(downloadPromise); } + if (promises.length === 0) { + console.log("downloadKeys: already have all necessary keys"); + } + return q.all(promises).then(() => { return this._getDevicesFromStore(userIds); }); diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index f7d7b770e..0e65b4f23 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -183,6 +183,7 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) { } if (!session) { + console.log(`Starting new megolm session for room ${self._roomId}`); session = self._prepareNewSession(); } @@ -353,6 +354,8 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse // TODO: retries return self._baseApis.sendToDevice("m.room.encrypted", contentMap); }).then(function() { + console.log(`Completed megolm keyshare in ${self._roomId}`); + // Add the devices we have shared with to session.sharedWithDevices. // // we deliberately iterate over devicesByUser (ie, the devices we @@ -387,6 +390,8 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse */ MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) { const self = this; + console.log(`Starting to encrypt event for ${this._roomId}`); + return this._getDevicesInRoom(room).then(function(devicesInRoom) { // check if any of these devices are not yet known to the user. // if so, warn the user so they can verify or ignore. diff --git a/src/models/room.js b/src/models/room.js index 1d0d7d97f..a1f88cd7c 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -752,6 +752,8 @@ ALLOWED_TRANSITIONS[EventStatus.CANCELLED] = * @fires module:client~MatrixClient#event:"Room.localEchoUpdated" */ Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) { + console.log(`setting pendingEvent status to ${newStatus} in ${event.getRoomId()}`); + // if the message was sent, we expect an event id if (newStatus == EventStatus.SENT && !newEventId) { throw new Error("updatePendingEvent called with status=SENT, " + From ed3cdeec74a5540f02e5fcd36145c9c14f3c8a60 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 12 Jun 2017 15:17:53 +0100 Subject: [PATCH 06/13] Prepare changelog for v0.7.11 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4792a7cd0..bb40073ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.7.11](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.11) (2017-06-12) +================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.11-rc.1...v0.7.11) + + * Add a bunch of logging around sending messages + [\#460](https://github.com/matrix-org/matrix-js-sdk/pull/460) + Changes in [0.7.11-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.11-rc.1) (2017-06-09) ============================================================================================================ [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.10...v0.7.11-rc.1) From 79fa9444028a82e9e15d0bc4ae927a01d0b2b6ec Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 12 Jun 2017 15:17:53 +0100 Subject: [PATCH 07/13] v0.7.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8b2d1444b..f94e7a430 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "0.7.11-rc.1", + "version": "0.7.11", "description": "Matrix Client-Server SDK for Javascript", "main": "index.js", "scripts": { From a40b10f53ca7cb7bb75182caff4ae074ce918dc5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jun 2017 20:16:29 +0100 Subject: [PATCH 08/13] allow setting iceTransportPolicy to relay through forceTURN option Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/webrtc/call.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/webrtc/call.js b/src/webrtc/call.js index 6ae945e5f..a44e18ad6 100644 --- a/src/webrtc/call.js +++ b/src/webrtc/call.js @@ -71,6 +71,7 @@ const DEBUG = true; // set true to enable console logging. * @param {Object} opts Config options. * @param {string} opts.roomId The room ID for this call. * @param {Object} opts.webRtc The WebRTC globals from the browser. + * @param {boolean} opts.forceTURN whether relay through TURN should be forced. * @param {Object} opts.URL The URL global. * @param {Array} opts.turnServers Optional. A list of TURN servers. * @param {MatrixClient} opts.client The Matrix Client instance to send events to. @@ -79,6 +80,7 @@ function MatrixCall(opts) { this.roomId = opts.roomId; this.client = opts.client; this.webRtc = opts.webRtc; + this.forceTURN = opts.forceTURN; this.URL = opts.URL; // Array of Objects with urls, username, credential keys this.turnServers = opts.turnServers || []; @@ -1184,6 +1186,7 @@ const _createPeerConnection = function(self) { } const pc = new self.webRtc.RtcPeerConnection({ + iceTransportPolicy: self.forceTURN ? 'relay' : undefined, iceServers: servers, }); pc.oniceconnectionstatechange = hookCallback(self, self._onIceConnectionStateChanged); @@ -1293,9 +1296,11 @@ module.exports.setVideoInput = function(deviceId) { videoInput = deviceId; }; * Create a new Matrix call for the browser. * @param {MatrixClient} client The client instance to use. * @param {string} roomId The room the call is in. + * @param {Object?} options optional options map. + * @param {boolean} options.forceTURN whether relay through TURN should be forced. * @return {MatrixCall} the call or null if the browser doesn't support calling. */ -module.exports.createNewMatrixCall = function(client, roomId) { +module.exports.createNewMatrixCall = function(client, roomId, options) { const w = global.window; const doc = global.document; if (!w || !doc) { @@ -1351,6 +1356,8 @@ module.exports.createNewMatrixCall = function(client, roomId) { URL: w.URL, roomId: roomId, turnServers: client.getTurnServers(), + // call level options + forceTURN: options ? options.forceTURN : false, }; return new MatrixCall(opts); }; From 25a8c799512036ffcd821018465b06a77b5831d0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 15 Jun 2017 17:13:25 +0100 Subject: [PATCH 09/13] Prepare changelog for v0.7.12-rc.1 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb40073ed..59dc86398 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.7.12-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.12-rc.1) (2017-06-15) +============================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.11...v0.7.12-rc.1) + + * allow setting iceTransportPolicy to relay through forceTURN option + [\#462](https://github.com/matrix-org/matrix-js-sdk/pull/462) + Changes in [0.7.11](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.11) (2017-06-12) ================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.11-rc.1...v0.7.11) From ffd9a01e2f4489674d1a92e37936ce27dd3a3057 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 15 Jun 2017 17:13:26 +0100 Subject: [PATCH 10/13] v0.7.12-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f94e7a430..54c67d513 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "0.7.11", + "version": "0.7.12-rc.1", "description": "Matrix Client-Server SDK for Javascript", "main": "index.js", "scripts": { From 4d8dc1a0c44814f203bb4e0823a55c894e56d051 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Jun 2017 11:58:55 +0100 Subject: [PATCH 11/13] Prepare changelog for v0.7.12 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59dc86398..0109bee4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.7.12](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.12) (2017-06-19) +================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.12-rc.1...v0.7.12) + + * No changes + + Changes in [0.7.12-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.12-rc.1) (2017-06-15) ============================================================================================================ [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.11...v0.7.12-rc.1) From db66023102adfd7ecb3dde4db2bb2703b3a17a90 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Jun 2017 11:58:56 +0100 Subject: [PATCH 12/13] v0.7.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 54c67d513..5e004136c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "0.7.12-rc.1", + "version": "0.7.12", "description": "Matrix Client-Server SDK for Javascript", "main": "index.js", "scripts": { From 009c28ae5008d71448153521b2b7f328d50e7ab4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 19 Jun 2017 15:51:55 +0100 Subject: [PATCH 13/13] Improve error reporting from indexeddbstore.clearDatabase - to help understand when it gets stuck in tests --- src/store/indexeddb-local-backend.js | 23 +++++++++++++++++++++-- src/store/indexeddb.js | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/store/indexeddb-local-backend.js b/src/store/indexeddb-local-backend.js index 7f87c5739..ccf330d96 100644 --- a/src/store/indexeddb-local-backend.js +++ b/src/store/indexeddb-local-backend.js @@ -163,8 +163,27 @@ LocalIndexedDBStoreBackend.prototype = { * @return {Promise} Resolved when the database is cleared. */ clearDatabase: function() { - console.log("Removing indexeddb instance: ", this._dbName); - return promiseifyRequest(this.indexedDB.deleteDatabase(this._dbName)); + return new q.Promise((resolve, reject) => { + console.log(`Removing indexeddb instance: ${this._dbName}`); + const req = this.indexedDB.deleteDatabase(this._dbName); + + req.onblocked = () => { + reject(new Error( + "unable to delete indexeddb because it is open elsewhere", + )); + }; + + req.onerror = (ev) => { + reject(new Error( + "unable to delete indexeddb: " + ev.target.error, + )); + }; + + req.onsuccess = () => { + console.log(`Removed indexeddb instance: ${this._dbName}`); + resolve(); + }; + }); }, /** diff --git a/src/store/indexeddb.js b/src/store/indexeddb.js index e2172dcb7..d1387eb50 100644 --- a/src/store/indexeddb.js +++ b/src/store/indexeddb.js @@ -150,7 +150,7 @@ IndexedDBStore.prototype.deleteAllData = function() { return this.backend.clearDatabase().then(() => { console.log("Deleted indexeddb data."); }, (err) => { - console.error("Failed to delete indexeddb data: ", err); + console.error(`Failed to delete indexeddb data: ${err}`); throw err; }); };