diff --git a/lib/client.js b/lib/client.js index fa3e67846..86b525c1b 100644 --- a/lib/client.js +++ b/lib/client.js @@ -17,6 +17,7 @@ var Room = require("./models/room"); var User = require("./models/user"); var webRtcCall = require("./webrtc/call"); var utils = require("./utils"); +var contentRepo = require("./content-repo"); var CRYPTO_ENABLED = false; @@ -1403,67 +1404,6 @@ MatrixClient.prototype.setAvatarUrl = function(url, callback) { ); }; -/** - * Get the avatar URL for a room member. This method is experimental and - * may change. - * @param {module:room-member.RoomMember} member - * @param {Number} width The desired width of the thumbnail. - * @param {Number} height The desired height of the thumbnail. - * @param {string} resizeMethod The thumbnail resize method to use, either - * "crop" or "scale". - * @param {Boolean} allowDefault (optional) Passing false causes this method to - * return null if the user has no avatar image. Otherwise, a default image URL - * will be returned. - * @return {?string} the avatar URL or null. - */ -MatrixClient.prototype.getAvatarUrlForMember = - function(member, width, height, resizeMethod, allowDefault) { - if (!member || !member.events.member) { - return null; - } - if (allowDefault === undefined) { allowDefault = true; } - var rawUrl = member.events.member.getContent().avatar_url; - if (rawUrl) { - return this._http.getHttpUriForMxc(rawUrl, width, height, resizeMethod); - } else if (allowDefault) { - return this._http.getIdenticonUri(member.userId, width, height); - } - return null; -}; - -/** - * Get the avatar URL for a room. This method is experimental and - * may change. - * @param {module:room.Room} room - * @param {Number} width The desired width of the thumbnail. - * @param {Number} height The desired height of the thumbnail. - * @param {string} resizeMethod The thumbnail resize method to use, either - * "crop" or "scale". - * @param {Boolean} allowDefault (optional) Passing false causes this method to - * return null if the user has no avatar image. Otherwise, a default image URL - * will be returned. - * @return {?string} the avatar URL or null. - */ -MatrixClient.prototype.getAvatarUrlForRoom = - function(room, width, height, resizeMethod, allowDefault) { - - if (!room || !room.currentState || !room.currentState.members) { - return null; - } - - var userId = this.credentials.userId; - var members = utils.filter(room.currentState.getMembers(), function(m) { - return (m.membership === "join" && m.userId !== userId); - }); - - if (members[0]) { - return this.getAvatarUrlForMember( - members[0], width, height, resizeMethod, allowDefault - ); - } - return null; -}; - /** * Turn an MXC URL into an HTTP one. This method is experimental and * may change. @@ -1476,7 +1416,9 @@ MatrixClient.prototype.getAvatarUrlForRoom = */ MatrixClient.prototype.mxcUrlToHttp = function(mxcUrl, width, height, resizeMethod) { - return this._http.getHttpUriForMxc(mxcUrl, width, height, resizeMethod); + return contentRepo.getHttpUriForMxc( + this.baseUrl, mxcUrl, width, height, resizeMethod + ); }; /** diff --git a/lib/content-repo.js b/lib/content-repo.js new file mode 100644 index 000000000..480f940c0 --- /dev/null +++ b/lib/content-repo.js @@ -0,0 +1,77 @@ +var utils = require("./utils"); + +module.exports = { + /** + * Get the HTTP URL for an MXC URI. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} mxc The mxc:// URI. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @return {string} The complete URL to the content. + */ + getHttpUriForMxc: function(baseUrl, mxc, width, height, resizeMethod) { + if (typeof mxc !== "string" || !mxc) { + return mxc; + } + if (mxc.indexOf("mxc://") !== 0) { + return mxc; + } + var serverAndMediaId = mxc.slice(6); // strips mxc:// + var prefix = "/_matrix/media/v1/download/"; + var params = {}; + + if (width) { + params.width = width; + } + if (height) { + params.height = height; + } + if (resizeMethod) { + params.method = resizeMethod; + } + if (utils.keys(params).length > 0) { + // these are thumbnailing params so they probably want the + // thumbnailing API... + prefix = "/_matrix/media/v1/thumbnail/"; + } + + var fragmentOffset = serverAndMediaId.indexOf("#"), + fragment = ""; + if (fragmentOffset >= 0) { + fragment = serverAndMediaId.substr(fragmentOffset); + serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); + } + return baseUrl + prefix + serverAndMediaId + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))) + fragment; + }, + + /** + * Get an identicon URL from an arbitrary string. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} identiconString The string to create an identicon for. + * @param {Number} width The desired width of the image in pixels. + * @param {Number} height The desired height of the image in pixels. + * @return {string} The complete URL to the identicon. + */ + getIdenticonUri: function(baseUrl, identiconString, width, height) { + if (!identiconString) { + return; + } + if (!width) { width = 96; } + if (!height) { height = 96; } + var params = { + width: width, + height: height + }; + + var path = utils.encodeUri("/_matrix/media/v1/identicon/$ident", { + $ident: identiconString + }); + return baseUrl + path + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))); + } +}; diff --git a/lib/http-api.js b/lib/http-api.js index d771471f7..e192dfa91 100644 --- a/lib/http-api.js +++ b/lib/http-api.js @@ -54,81 +54,6 @@ module.exports.MatrixHttpApi = function MatrixHttpApi(opts) { module.exports.MatrixHttpApi.prototype = { - // URI functions - // ============= - - /** - * Get the HTTP URL for an MXC URI. - * @param {string} mxc The mxc:// URI. - * @param {Number} width The desired width of the thumbnail. - * @param {Number} height The desired height of the thumbnail. - * @param {string} resizeMethod The thumbnail resize method to use, either - * "crop" or "scale". - * @return {string} The complete URL to the content. - */ - getHttpUriForMxc: function(mxc, width, height, resizeMethod) { - if (typeof mxc !== "string" || !mxc) { - return mxc; - } - if (mxc.indexOf("mxc://") !== 0) { - return mxc; - } - var serverAndMediaId = mxc.slice(6); // strips mxc:// - var prefix = "/_matrix/media/v1/download/"; - var params = {}; - - if (width) { - params.width = width; - } - if (height) { - params.height = height; - } - if (resizeMethod) { - params.method = resizeMethod; - } - if (utils.keys(params).length > 0) { - // these are thumbnailing params so they probably want the - // thumbnailing API... - prefix = "/_matrix/media/v1/thumbnail/"; - } - - var fragmentOffset = serverAndMediaId.indexOf("#"), - fragment = ""; - if (fragmentOffset >= 0) { - fragment = serverAndMediaId.substr(fragmentOffset); - serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); - } - return this.opts.baseUrl + prefix + serverAndMediaId + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))) + fragment; - }, - - /** - * Get an identicon URL from an arbitrary string. - * @param {string} identiconString The string to create an identicon for. - * @param {Number} width The desired width of the image in pixels. - * @param {Number} height The desired height of the image in pixels. - * @return {string} The complete URL to the identicon. - */ - getIdenticonUri: function(identiconString, width, height) { - if (!identiconString) { - return; - } - if (!width) { width = 96; } - if (!height) { height = 96; } - var params = { - width: width, - height: height - }; - - var path = utils.encodeUri("/_matrix/media/v1/identicon/$ident", { - $ident: identiconString - }); - return this.opts.baseUrl + path + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))); - }, - /** * Get the content repository url with query parameters. * @return {Object} An object with a 'base', 'path' and 'params' for base URL, diff --git a/lib/models/room-member.js b/lib/models/room-member.js index 3fcdbca36..b836fc2be 100644 --- a/lib/models/room-member.js +++ b/lib/models/room-member.js @@ -3,6 +3,7 @@ * @module models/room-member */ var EventEmitter = require("events").EventEmitter; +var contentRepo = require("../content-repo"); var utils = require("../utils"); @@ -147,6 +148,38 @@ RoomMember.prototype.getLastModifiedTime = function() { return this._modified; }; +/** + * Get the avatar URL for a room member. + * @param {string} baseUrl The base homeserver URL + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDefault (optional) Passing false causes this method to + * return null if the user has no avatar image. Otherwise, a default image URL + * will be returned. Default: true. + * @return {?string} the avatar URL or null. + */ +RoomMember.prototype.getAvatarUrl = + function(baseUrl, width, height, resizeMethod, allowDefault) { + if (!this.events.member) { + return null; + } + if (allowDefault === undefined) { allowDefault = true; } + var rawUrl = this.events.member.getContent().avatar_url; + if (rawUrl) { + return contentRepo.getHttpUriForMxc( + baseUrl, rawUrl, width, height, resizeMethod + ); + } + else if (allowDefault) { + return contentRepo.getIdenticonUri( + baseUrl, member.userId, width, height + ); + } + return null; +}; + function calculateDisplayName(member, event, roomState) { var displayName = event.getDirectionalContent().displayname; var selfUserId = member.userId; diff --git a/lib/models/room.js b/lib/models/room.js index 3e398c50f..475d5e365 100644 --- a/lib/models/room.js +++ b/lib/models/room.js @@ -7,6 +7,7 @@ var EventEmitter = require("events").EventEmitter; var RoomState = require("./room-state"); var RoomSummary = require("./room-summary"); var utils = require("../utils"); +var contentRepo = require("../content-repo"); /** * Construct a new Room. @@ -39,6 +40,38 @@ function Room(roomId, storageToken) { } utils.inherits(Room, EventEmitter); +/** + * Get the avatar URL for a room if one was set. + * @param {String} baseUrl The homeserver base URL. See {@link MatrixClient#getHomeserverUrl()}. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {boolean} allowDefault True to allow an identicon for this room if an + * avatar URL wasn't explicitly set. Default: true. + * @return {?string} the avatar URL or null. + */ +Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod, allowDefault) { + var roomAvatarEvent = this.currentState.getStateEvents("m.room.avatar", ""); + if (!roomAvatarEvent) { + return null; + } + if (allowDefault === undefined) { allowDefault = true; } + var mainUrl = roomAvatarEvent.getContent().url; + if (mainUrl) { + return contentRepo.getHttpUriForMxc( + baseUrl, mainUrl, width, height, resizeMethod + ); + } + else if (allowDefault) { + return contentRepo.getIdenticonUri( + baseUrl, member.userId, width, height + ); + } + + return null; +}; + /** * Get a member from the current room state. * @param {string} userId The user ID of the member.