diff --git a/lib/client.js b/lib/client.js index ea0a67720..36a23e63c 100644 --- a/lib/client.js +++ b/lib/client.js @@ -903,6 +903,37 @@ MatrixClient.prototype.getUsers = function() { return this.store.getUsers(); }; +// User Account Data operations +// ============================ + +/** + * Set account data event for the current user. + * @param {string} eventType The event type + * @param {Object} the contents object for the event + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setAccountData = function(eventType, contents, callback) { + var path = utils.encodeUri("/user/$userId/account_data/$type", { + $userId: this.credentials.userId, + $type: eventType, + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, contents + ); +}; + +/** + * Get account data event of given type for the current user. + * @param {string} eventType The event type + * @param {module:client.callback} callback Optional. + * @return {?object} The contents of the given account data event + */ +MatrixClient.prototype.getAccountData = function(eventType) { + return this.store.getAccountData(eventType); +}; + // Room operations // =============== @@ -1086,23 +1117,6 @@ MatrixClient.prototype.deleteRoomTag = function(roomId, tagName, callback) { ); }; -/** - * @param {string} eventType event type to be set - * @param {object} content event content - * @param {module:client.callback} callback Optional. - * @return {module:client.Promise} Resolves: TODO - * @return {module:http-api.MatrixError} Rejects: with an error response. - */ -MatrixClient.prototype.setAccountData = function(eventType, content, callback) { - var path = utils.encodeUri("/user/$userId/account_data/$type", { - $userId: this.credentials.userId, - $type: eventType, - }); - return this._http.authedRequest( - callback, "PUT", path, undefined, content - ); -}; - /** * @param {string} roomId * @param {string} eventType event type to be set @@ -3991,7 +4005,7 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; * }); */ - /** +/** * Fires when a device is marked as verified/unverified/blocked/unblocked by * {@link module:client~MatrixClient#setDeviceVerified|MatrixClient.setDeviceVerified} or * {@link module:client~MatrixClient#setDeviceBlocked|MatrixClient.setDeviceBlocked}. @@ -4001,6 +4015,17 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; * @param {module:client~DeviceInfo} device information about the verified device */ +/** + * Fires whenever new user-scoped account_data is added. + * @event module:client~MatrixClient#"Room" + * @param {MatrixEvent} event The event describing the account_data just added + * @example + * matrixClient.on("accountData", function(event){ + * myAccountData[event.type] = event.content; + * }); + */ + + // EventEmitter JSDocs /** diff --git a/lib/store/memory.js b/lib/store/memory.js index af8e5392c..9db001fe7 100644 --- a/lib/store/memory.js +++ b/lib/store/memory.js @@ -43,6 +43,9 @@ module.exports.MatrixInMemoryStore = function MatrixInMemoryStore(opts) { // filterId: Filter // } }; + this.accountData = { + // type : content + }; this.localStorage = opts.localStorage; }; @@ -244,7 +247,26 @@ module.exports.MatrixInMemoryStore.prototype = { this.localStorage.setItem("mxjssdk_memory_filter_" + filterName, filterId); } catch (e) {} - } + }, + + /** + * Store user-scoped account data events + * @param {Array} events The events to store. + */ + storeAccountDataEvents: function(events) { + var self = this; + events.forEach(function(event) { + self.accountData[event.type] = event.content; + }); + }, + + /** + * Get account data event by event type + * @param {string} eventType The event type being queried + */ + getAccountData: function(eventType) { + return this.accountData[eventType]; + }, // TODO //setMaxHistoryPerRoom: function(maxHistory) {}, diff --git a/lib/store/stub.js b/lib/store/stub.js index 41fa7a25f..c635c93f6 100644 --- a/lib/store/stub.js +++ b/lib/store/stub.js @@ -162,7 +162,23 @@ StubStore.prototype = { */ setFilterIdByName: function(filterName, filterId) { - } + }, + + /** + * Store user-scoped account data events + * @param {Array} events The events to store. + */ + storeAccountDataEvents: function(events) { + + }, + + /** + * Get account data event by event type + * @param {string} eventType The event type being queried + */ + getAccountData: function(eventType) { + + }, // TODO //setMaxHistoryPerRoom: function(maxHistory) {}, diff --git a/lib/sync.js b/lib/sync.js index 0d34f3fa8..76741eeed 100644 --- a/lib/sync.js +++ b/lib/sync.js @@ -605,7 +605,19 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) { }); } - // the returned json structure is abit crap, so make it into a + // handle non-room account_data + if (data.account_data && utils.isArray(data.account_data.events)) { + client.store.storeAccountDataEvents( + data.account_data.events.map(client.getEventMapper()).map( + function(accountDataEvent) { + client.emit("accountData", accountDataEvent); + return accountDataEvent; + } + ) + ); + } + + // the returned json structure is a bit crap, so make it into a // nicer form (array) after applying sanity to make sure we don't fail // on missing keys (on the off chance) var inviteRooms = [];