/** * This file is part of Threema Web. * * Threema Web is free software: you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero * General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Threema Web. If not, see . */ import {bufferToUrl, logAdapter} from '../helpers'; import {isEchoContact, isGatewayContact} from '../receiver_helpers'; import {WebClientService} from '../services/webclient'; import {isContactReceiver} from '../typeguards'; export default [ '$rootScope', '$timeout', '$log', 'WebClientService', function($rootScope: ng.IRootScopeService, $timeout: ng.ITimeoutService, $log: ng.ILogService, webClientService: WebClientService) { return { restrict: 'E', scope: {}, bindToController: { receiver: '=eeeReceiver', resolution: '=eeeResolution', }, controllerAs: 'ctrl', controller: [function() { this.logTag = '[Directives.Avatar]'; let loadingPromise: ng.IPromise = null; /** * Convert avatar bytes to an URI. */ const avatarUri = { high: null, low: null, }; this.avatarToUri = (data: ArrayBuffer, res: 'high' | 'low') => { if (data === null || data === undefined) { return ''; } if (avatarUri[res] === null) { // Cache avatar image URI avatarUri[res] = bufferToUrl( data, webClientService.appCapabilities.imageFormat.avatar, logAdapter($log.warn, this.logTag), ); } return avatarUri[res]; }; this.$onInit = function() { this.highResolution = this.resolution === 'high'; this.isLoading = this.highResolution; this.backgroundColor = this.receiver.color; this.avatarClass = () => { return 'avatar-' + this.resolution + (this.isLoading ? ' is-loading' : ''); }; this.avatarExists = () => { if (this.receiver.avatar === undefined || this.receiver.avatar[this.resolution] === undefined || this.receiver.avatar[this.resolution] === null) { return false; } this.isLoading = false; // Reset background color this.backgroundColor = null; return true; }; /** * Return path to the default avatar. */ this.getDefaultAvatarUri = (type: threema.ReceiverType, highResolution: boolean) => { switch (type) { case 'group': return highResolution ? 'img/ic_group_picture_big.png' : 'img/ic_group_t.png'; case 'distributionList': return highResolution ? 'img/ic_distribution_list_t.png' : 'img/ic_distribution_list_t.png'; case 'contact': case 'me': default: return highResolution ? 'img/ic_contact_picture_big.png' : 'img/ic_contact_picture_t.png'; } }; /** * Return an avatar URI. * * This will fall back to a low resolution version or to the * default avatar if no avatar for the desired resolution could * be found. */ this.getAvatarUri = () => { /// If an avatar for the chosen resolution exists, convert it to an URI and return if (this.avatarExists()) { return this.avatarToUri(this.receiver.avatar[this.resolution], this.resolution); } // Otherwise, if we requested a high res avatar but // there is only a low-res version, show that. if (this.highResolution && this.receiver.avatar !== undefined && this.receiver.avatar.low !== undefined && this.receiver.avatar.low !== null) { return this.avatarToUri(this.receiver.avatar.low, 'low'); } // As a fallback, get the default avatar. return this.getDefaultAvatarUri(this.receiver.type, this.highResolution); }; this.requestAvatar = (inView: boolean) => { if (this.avatarExists()) { // do not request return; } if (inView) { if (loadingPromise === null) { // Do not wait on high resolution avatar const loadingTimeout = this.highResolution ? 0 : 500; loadingPromise = $timeout(() => { // show loading only on high res images! webClientService.requestAvatar({ type: this.receiver.type, id: this.receiver.id, } as threema.Receiver, this.highResolution).then((avatar) => { $rootScope.$apply(() => { this.isLoading = false; }); }).catch(() => { $rootScope.$apply(() => { this.isLoading = false; }); }); }, loadingTimeout); } } else if (loadingPromise !== null) { // Cancel pending avatar loading $timeout.cancel(loadingPromise); loadingPromise = null; } }; const isWork = webClientService.clientInfo.isWork; this.showWorkIndicator = () => { if (!isContactReceiver(this.receiver)) { return false; } const contact: threema.ContactReceiver = this.receiver; return isWork === false && !this.highResolution && contact.identityType === threema.IdentityType.Work; }; this.showHomeIndicator = () => { if (!isContactReceiver(this.receiver)) { return false; } const contact: threema.ContactReceiver = this.receiver; return isWork === true && !isGatewayContact(contact) && !isEchoContact(contact) && contact.identityType === threema.IdentityType.Regular && !this.highResolution; }; this.showBlocked = () => { if (!isContactReceiver(this.receiver)) { return false; } const contact: threema.ContactReceiver = this.receiver; return !this.highResolution && contact.isBlocked; }; }; }], template: `
Threema Work user
Private Threema contact
blocked icon
`, }; }, ];