diff --git a/src/domain/avatar.js b/src/domain/avatar.js index f94ba3b2..5b32020b 100644 --- a/src/domain/avatar.js +++ b/src/domain/avatar.js @@ -47,3 +47,11 @@ function hashCode(str) { export function getIdentifierColorNumber(id) { return (hashCode(id) % 8) + 1; } + +export function getAvatarHttpUrl(avatarUrl, cssSize, platform, mediaRepository) { + if (avatarUrl) { + const imageSize = cssSize * platform.devicePixelRatio; + return mediaRepository.mxcUrlThumbnail(avatarUrl, imageSize, imageSize, "crop"); + } + return null; +} diff --git a/src/domain/session/leftpanel/BaseTileViewModel.js b/src/domain/session/leftpanel/BaseTileViewModel.js index d4ca3293..360f2b39 100644 --- a/src/domain/session/leftpanel/BaseTileViewModel.js +++ b/src/domain/session/leftpanel/BaseTileViewModel.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {avatarInitials, getIdentifierColorNumber} from "../../avatar.js"; +import {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from "../../avatar.js"; import {ViewModel} from "../../ViewModel.js"; const KIND_ORDER = ["invite", "room"]; @@ -75,12 +75,8 @@ export class BaseTileViewModel extends ViewModel { return getIdentifierColorNumber(this._avatarSource.id); } - get avatarUrl() { - if (this._avatarSource.avatarUrl) { - const size = 32 * this.platform.devicePixelRatio; - return this._avatarSource.mediaRepository.mxcUrlThumbnail(this._avatarSource.avatarUrl, size, size, "crop"); - } - return null; + avatarUrl(size) { + return getAvatarHttpUrl(this._avatarSource.avatarUrl, size, this.platform, this._avatarSource.mediaRepository); } get avatarTitle() { diff --git a/src/domain/session/room/InviteViewModel.js b/src/domain/session/room/InviteViewModel.js index 57691a34..15fcb5a5 100644 --- a/src/domain/session/room/InviteViewModel.js +++ b/src/domain/session/room/InviteViewModel.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {avatarInitials, getIdentifierColorNumber} from "../../avatar.js"; +import {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from "../../avatar.js"; import {ViewModel} from "../../ViewModel.js"; export class InviteViewModel extends ViewModel { @@ -60,12 +60,8 @@ export class InviteViewModel extends ViewModel { return getIdentifierColorNumber(this._invite.id) } - get avatarUrl() { - if (this._invite.avatarUrl) { - const size = 128 * this.platform.devicePixelRatio; - return this._mediaRepository.mxcUrlThumbnail(this._invite.avatarUrl, size, size, "crop"); - } - return null; + avatarUrl(size) { + return getAvatarHttpUrl(this._invite.avatarUrl, size, this.platform, this._mediaRepository); } _createRoomDescription() { @@ -153,12 +149,8 @@ class RoomMemberViewModel { return getIdentifierColorNumber(this._member.userId); } - get avatarUrl() { - if (this._member.avatarUrl) { - const size = 24 * this._platform.devicePixelRatio; - return this._mediaRepository.mxcUrlThumbnail(this._member.avatarUrl, size, size, "crop"); - } - return null; + avatarUrl(size) { + return getAvatarHttpUrl(this._member.avatarUrl, size, this._platform, this._mediaRepository); } get avatarTitle() { diff --git a/src/domain/session/room/RoomViewModel.js b/src/domain/session/room/RoomViewModel.js index e3e40c2a..63aa6811 100644 --- a/src/domain/session/room/RoomViewModel.js +++ b/src/domain/session/room/RoomViewModel.js @@ -16,7 +16,7 @@ limitations under the License. */ import {TimelineViewModel} from "./timeline/TimelineViewModel.js"; -import {avatarInitials, getIdentifierColorNumber} from "../../avatar.js"; +import {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from "../../avatar.js"; import {ViewModel} from "../../ViewModel.js"; export class RoomViewModel extends ViewModel { @@ -120,12 +120,8 @@ export class RoomViewModel extends ViewModel { return getIdentifierColorNumber(this._room.id) } - get avatarUrl() { - if (this._room.avatarUrl) { - const size = 32 * this.platform.devicePixelRatio; - return this._room.mediaRepository.mxcUrlThumbnail(this._room.avatarUrl, size, size, "crop"); - } - return null; + avatarUrl(size) { + return getAvatarHttpUrl(this._room.avatarUrl, size, this.platform, this._room.mediaRepository); } get avatarTitle() { diff --git a/src/domain/session/room/timeline/tiles/MessageTile.js b/src/domain/session/room/timeline/tiles/MessageTile.js index fe566814..f85f0fca 100644 --- a/src/domain/session/room/timeline/tiles/MessageTile.js +++ b/src/domain/session/room/timeline/tiles/MessageTile.js @@ -15,7 +15,7 @@ limitations under the License. */ import {SimpleTile} from "./SimpleTile.js"; -import {getIdentifierColorNumber, avatarInitials} from "../../../../avatar.js"; +import {getIdentifierColorNumber, avatarInitials, getAvatarHttpUrl} from "../../../../avatar.js"; export class MessageTile extends SimpleTile { constructor(options) { @@ -50,11 +50,8 @@ export class MessageTile extends SimpleTile { return getIdentifierColorNumber(this._entry.sender); } - get avatarUrl() { - if (this._entry.avatarUrl) { - return this._mediaRepository.mxcUrlThumbnail(this._entry.avatarUrl, 30, 30, "crop"); - } - return null; + avatarUrl(size) { + return getAvatarHttpUrl(this._entry.avatarUrl, size, this.platform, this._mediaRepository); } get avatarLetter() { diff --git a/src/platform/web/ui/avatar.js b/src/platform/web/ui/avatar.js index 596a8a2c..8845f887 100644 --- a/src/platform/web/ui/avatar.js +++ b/src/platform/web/ui/avatar.js @@ -37,8 +37,8 @@ export class AvatarView extends BaseUpdateView { } _avatarUrlChanged() { - if (this.value.avatarUrl !== this._avatarUrl) { - this._avatarUrl = this.value.avatarUrl; + if (this.value.avatarUrl(this._size) !== this._avatarUrl) { + this._avatarUrl = this.value.avatarUrl(this._size); return true; } return false; @@ -79,7 +79,7 @@ export class AvatarView extends BaseUpdateView { if (this._avatarUrlChanged()) { // avatarColorNumber won't change, it's based on room/user id const bgColorClass = `usercolor${vm.avatarColorNumber}`; - if (vm.avatarUrl) { + if (vm.avatarUrl(this._size)) { this._root.replaceChild(renderImg(vm, this._size), this._root.firstChild); this._root.classList.remove(bgColorClass); } else { @@ -87,7 +87,7 @@ export class AvatarView extends BaseUpdateView { this._root.classList.add(bgColorClass); } } - const hasAvatar = !!vm.avatarUrl; + const hasAvatar = !!vm.avatarUrl(this._size); if (this._avatarTitleChanged() && hasAvatar) { const img = this._root.firstChild; img.setAttribute("title", vm.avatarTitle); @@ -104,7 +104,7 @@ export class AvatarView extends BaseUpdateView { * @return {Element} */ export function renderStaticAvatar(vm, size, extraClasses = undefined) { - const hasAvatar = !!vm.avatarUrl; + const hasAvatar = !!vm.avatarUrl(size); let avatarClasses = classNames({ avatar: true, [`size-${size}`]: true, @@ -119,5 +119,5 @@ export function renderStaticAvatar(vm, size, extraClasses = undefined) { function renderImg(vm, size) { const sizeStr = size.toString(); - return tag.img({src: vm.avatarUrl, width: sizeStr, height: sizeStr, title: vm.avatarTitle}); + return tag.img({src: vm.avatarUrl(size), width: sizeStr, height: sizeStr, title: vm.avatarTitle}); } diff --git a/src/platform/web/ui/css/avatar.css b/src/platform/web/ui/css/avatar.css index 15f2222b..6e68236f 100644 --- a/src/platform/web/ui/css/avatar.css +++ b/src/platform/web/ui/css/avatar.css @@ -53,6 +53,14 @@ limitations under the License. font-size: calc(var(--avatar-size) * 0.6); } +.hydrogen .avatar.size-30 { + --avatar-size: 30px; + width: var(--avatar-size); + height: var(--avatar-size); + line-height: var(--avatar-size); + font-size: calc(var(--avatar-size) * 0.6); +} + .hydrogen .avatar.size-24 { --avatar-size: 24px; width: var(--avatar-size);