diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 907dc16d2ed..d42e3dee5d5 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -16,6 +16,8 @@ import { ServicesModule } from './services/services.module';
import { AppComponent } from './app.component';
import { ModalComponent } from './modal.component';
+import { AvatarComponent } from './components/avatar.component';
+
import { FooterComponent } from './layouts/footer.component';
import { FrontendLayoutComponent } from './layouts/frontend-layout.component';
import { NavbarComponent } from './layouts/navbar.component';
@@ -87,6 +89,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
AppComponent,
AttachmentsComponent,
AutofocusDirective,
+ AvatarComponent,
BlurClickDirective,
BoxRowDirective,
BulkDeleteComponent,
diff --git a/src/app/components/avatar.component.ts b/src/app/components/avatar.component.ts
new file mode 100644
index 00000000000..bd294db407a
--- /dev/null
+++ b/src/app/components/avatar.component.ts
@@ -0,0 +1,113 @@
+import {
+ Component,
+ Input,
+ OnChanges,
+ OnInit,
+} from '@angular/core';
+import { DomSanitizer } from '@angular/platform-browser';
+
+@Component({
+ selector: 'app-avatar',
+ template: '',
+})
+export class AvatarComponent implements OnChanges, OnInit {
+ @Input() data: string;
+ @Input() width = 45;
+ @Input() height = 45;
+ @Input() charCount = 2;
+ @Input() textColor = '#ffffff';
+ @Input() fontSize = 20;
+ @Input() fontWeight = 300;
+ @Input() dynamic = false;
+
+ src: string;
+
+ constructor(public sanitizer: DomSanitizer) { }
+
+ ngOnInit() {
+ if (!this.dynamic) {
+ this.generate();
+ }
+ }
+
+ ngOnChanges() {
+ if (this.dynamic) {
+ this.generate();
+ }
+ }
+
+ private generate() {
+ let chars: string = null;
+ const upperData = this.data.toUpperCase();
+
+ if (this.charCount > 1) {
+ chars = this.getFirstLetters(upperData, this.charCount);
+ }
+ if (chars == null) {
+ chars = upperData.substr(0, this.charCount);
+ }
+
+ const charObj = this.getCharText(chars);
+ const color = this.stringToColor(upperData);
+ const svg = this.getSvg(this.width, this.height, color);
+ svg.appendChild(charObj);
+ const html = window.document.createElement('div').appendChild(svg).outerHTML;
+ const svgHtml = window.btoa(unescape(encodeURIComponent(html)));
+ this.src = 'data:image/svg+xml;base64,' + svgHtml;
+ }
+
+ private stringToColor(str: string): string {
+ let hash = 0;
+ for (let i = 0; i < str.length; i++) {
+ // tslint:disable-next-line
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
+ }
+ let color = '#';
+ for (let i = 0; i < 3; i++) {
+ // tslint:disable-next-line
+ const value = (hash >> (i * 8)) & 0xFF;
+ color += ('00' + value.toString(16)).substr(-2);
+ }
+ return color;
+ }
+
+ private getFirstLetters(data: string, count: number): string {
+ const parts = data.split(' ');
+ if (parts.length > 1) {
+ let text = '';
+ for (let i = 0; i < count; i++) {
+ text += parts[i].substr(0, 1);
+ }
+ return text;
+ }
+ return null;
+ }
+
+ private getSvg(width: number, height: number, color: string): HTMLElement {
+ const svgTag = window.document.createElement('svg');
+ svgTag.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+ svgTag.setAttribute('pointer-events', 'none');
+ svgTag.setAttribute('width', width.toString());
+ svgTag.setAttribute('height', height.toString());
+ svgTag.style.backgroundColor = color;
+ svgTag.style.width = width + 'px';
+ svgTag.style.height = height + 'px';
+ return svgTag;
+ }
+
+ private getCharText(character: string): HTMLElement {
+ const textTag = window.document.createElement('text');
+ textTag.setAttribute('text-anchor', 'middle');
+ textTag.setAttribute('y', '50%');
+ textTag.setAttribute('x', '50%');
+ textTag.setAttribute('dy', '0.35em');
+ textTag.setAttribute('pointer-events', 'auto');
+ textTag.setAttribute('fill', this.textColor);
+ textTag.setAttribute('font-family', '"Open Sans","Helvetica Neue",Helvetica,Arial,' +
+ 'sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"');
+ textTag.textContent = character;
+ textTag.style.fontWeight = this.fontWeight.toString();
+ textTag.style.fontSize = this.fontSize + 'px';
+ return textTag;
+ }
+}
diff --git a/src/app/settings/account.component.html b/src/app/settings/account.component.html
index 33bcbc7d133..81de6d92a9b 100644
--- a/src/app/settings/account.component.html
+++ b/src/app/settings/account.component.html
@@ -20,6 +20,9 @@
+