@deepkit/desktop-ui
Version:
Library for desktop UI widgets in Angular 10+
249 lines (211 loc) • 8.24 kB
text/typescript
/*
* Deepkit Framework
* Copyright (C) 2021 Deepkit UG, Marc J. Schmidt
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the MIT License.
*
* You should have received a copy of the MIT License along with this program.
*/
import {
AfterViewInit,
ChangeDetectorRef,
Component,
ComponentFactoryResolver,
ComponentRef,
Directive,
ElementRef,
EventEmitter,
HostListener,
Input,
OnChanges,
OnDestroy,
Output,
SimpleChanges,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import * as emojis from './emojis';
import { EmojiCategory } from './emojis';
import { DropdownComponent } from '../button';
export class EmojiDropdownComponent implements AfterViewInit {
blacklist: string[] = [];
lastEmojis: string[] = [];
lastEmojisChange = new EventEmitter();
emoji: string = '';
emojiChange = new EventEmitter();
dropdown!: DropdownComponent;
emojis = emojis;
search: string = '';
categories: string[] = [
'Smileys & People',
'Animals & Nature',
'Food & Drink',
'Activities',
'Travel & Places',
'Objects',
'Symbols',
'Flags',
];
constructor(protected element: ElementRef, protected cd: ChangeDetectorRef) {
}
getLast(emojis: string[]): string[] | undefined {
if (!emojis.length) return;
return [...new Set(emojis.map(v => {
if (v[0] === ':') return v.substring(1, v.length - 1);
return v[0];
}))];
}
ngAfterViewInit() {
this.element.nativeElement.remove();
}
public open(target: ElementRef) {
if (this.search) {
this.search = '';
this.cd.detectChanges();
}
this.dropdown.toggle(target);
if (this.emoji) {
const element = document.getElementById('emoji_' + this.emoji);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}
}
find(search: string): string[] {
search = search.toLowerCase();
const result: string[] = [];
for (const emoji of Object.values(emojis.emojis)) {
if (-1 !== emoji.name.toLowerCase().indexOf(search)) {
result.push(emoji.shortName);
}
}
return result;
}
choose(name: string) {
name = ':' + name + ':';
this.emoji = name;
this.emojiChange.emit(name);
if (-1 === this.lastEmojis.indexOf(name)) {
this.lastEmojis.push(name);
} else {
const index = this.lastEmojis.indexOf(name);
if (index > 0) {
this.lastEmojis.splice(index, 1);
this.lastEmojis.splice(index - 1, 0, name);
}
}
this.lastEmojis = this.lastEmojis.slice(0);
this.dropdown.close();
this.cd.detectChanges();
}
getCategory(name: string): EmojiCategory {
for (const category of emojis.categories) {
if (category.name === name) return category;
}
throw new Error(`No category for name ${name} found`);
}
}
export class EmojiDropdownDirective implements OnChanges, AfterViewInit, OnDestroy {
protected dropdown?: ComponentRef<EmojiDropdownComponent>;
lastEmojis: string[] = [];
lastEmojisChange = new EventEmitter();
blacklist: string[] = [];
emoji: string = '';
emojiChange = new EventEmitter();
constructor(
protected elementRef: ElementRef,
protected view: ViewContainerRef,
protected resolver: ComponentFactoryResolver,
) {
}
ngAfterViewInit() {
const factory = this.resolver.resolveComponentFactory(EmojiDropdownComponent);
this.dropdown = this.view.createComponent(factory);
this.dropdown.instance.emojiChange = this.emojiChange;
this.dropdown.instance.lastEmojisChange = this.lastEmojisChange;
this.dropdown.instance.blacklist = this.blacklist;
this.dropdown.instance.lastEmojis = this.lastEmojis;
this.dropdown.instance.emoji = this.emoji;
this.dropdown.changeDetectorRef.detectChanges();
}
ngOnChanges(changes: SimpleChanges): void {
if (this.dropdown) {
this.dropdown.instance.blacklist = this.blacklist;
this.dropdown.instance.emoji = this.emoji;
this.dropdown.instance.lastEmojis = this.lastEmojis;
this.dropdown.changeDetectorRef.detectChanges();
}
}
onClick() {
if (this.dropdown) {
this.dropdown.instance.open(this.elementRef);
}
}
ngOnDestroy() {
if (this.dropdown) {
this.dropdown.destroy();
}
}
}