first iteration of emoji support #47

This commit is contained in:
Nicolas Constant 2019-04-13 23:04:19 -04:00
parent ba2479915a
commit 8ecbd53b5b
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
8 changed files with 306 additions and 81 deletions

316
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,7 @@
"@ngxs/store": "^3.2.0",
"bootstrap": "^4.1.3",
"core-js": "^2.5.4",
"emojione": "^4.5.0",
"ionicons": "^4.4.3",
"rxjs": "^6.4.0",
"tslib": "^1.9.0",

View File

@ -29,7 +29,7 @@
<img *ngIf="notificationAccount" class="notification--avatar" src="{{ notificationAccount.avatar }}" />
<span class="status__name">
<span class="status__name--displayname"
innerHTML="{{displayedStatus.account.display_name}}"></span><span
innerHTML="{{statusAccountName}}"></span><span
class="status__name--username">{{displayedStatus.account.acct}}</span>
</span>
</a>
@ -61,7 +61,7 @@
<span class="status__content-warning--title">sensitive content</span>
{{ contentWarningText }}
</a>
<app-databinded-text class="status__content" *ngIf="!isContentWarned" [text]="displayedStatus.content"
<app-databinded-text class="status__content" *ngIf="!isContentWarned" [text]="statusContent"
(accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)"
(textSelected)="textSelected()"></app-databinded-text>
<app-attachements *ngIf="!isContentWarned && hasAttachments" class="attachments"

View File

@ -1,4 +1,5 @@
@import "variables";
@import "commons";
.reblog {
position: relative;
margin: 5px 0 0 10px;

View File

@ -2,9 +2,10 @@ import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from "@angu
import { faStar, faRetweet } from "@fortawesome/free-solid-svg-icons";
import { Status, Account } from "../../../services/models/mastodon.interfaces";
import { OpenThreadEvent } from "../../../services/tools.service";
import { OpenThreadEvent, ToolsService } from "../../../services/tools.service";
import { ActionBarComponent } from "./action-bar/action-bar.component";
import { StatusWrapper } from '../../../models/common.model';
import { EmojiConverter, EmojiTypeEnum } from '../../../tools/emoji.tools';
@Component({
selector: "app-status",
@ -12,10 +13,16 @@ import { StatusWrapper } from '../../../models/common.model';
styleUrls: ["./status.component.scss"]
})
export class StatusComponent implements OnInit {
private emojiConverter = new EmojiConverter();
faStar = faStar;
faRetweet = faRetweet;
displayedStatus: Status;
statusAccountName: string;
statusContent: string;
reblog: boolean;
hasAttachments: boolean;
replyingToStatus: boolean;
@ -59,6 +66,12 @@ export class StatusComponent implements OnInit {
if (this.displayedStatus.media_attachments && this.displayedStatus.media_attachments.length > 0) {
this.hasAttachments = true;
}
// const instanceUrl = 'https://' + this.status.uri.split('https://')[1].split('/')[0];
this.statusAccountName = this.emojiConverter.applyEmojis(this.displayedStatus.account.emojis, this.displayedStatus.account.display_name, EmojiTypeEnum.small, this.status.uri);
this.statusContent = this.emojiConverter.applyEmojis(this.displayedStatus.emojis, this.displayedStatus.content, EmojiTypeEnum.medium, this.status.uri);
}
get statusWrapper(): StatusWrapper {
return this._statusWrapper;

View File

@ -162,7 +162,7 @@ export interface Status {
mentions: Mention[];
tags: Tag[];
application: Application;
emojis: any[];
emojis: Emoji[];
language: string;
pinned: boolean;

View File

@ -0,0 +1,36 @@
import { Emoji } from '../services/models/mastodon.interfaces';
import * as EmojiOne from 'emojione';
export class EmojiConverter {
applyEmojis(emojis: Emoji[], text: string, type: EmojiTypeEnum, url: string): string {
const instanceUrl = 'https://' + url.split('https://')[1].split('/')[0];
let className = 'emoji-small';
if (type === EmojiTypeEnum.medium) {
className = 'emoji-medium';
}
emojis.forEach(emoji => {
text = text.replace(`:${emoji.shortcode}:`, `<img class="${className}" src="${emoji.url}" title=":${emoji.shortcode}:" alt=":${emoji.shortcode}:" />`);
});
text = EmojiOne.toImage(text);
while (text.includes('class="emojione"')) {
text = text.replace('class="emojione"', `class="emojione ${className}" onerror="this.style.display='none'"`);
}
//FIXME: clean up this mess...
while (text.includes('https://cdn.jsdelivr.net/emojione/assets/4.5/png/32/')) {
text = text.replace('https://cdn.jsdelivr.net/emojione/assets/4.5/png/32/', instanceUrl + '/emoji/');
text = text.replace('.png', '.svg');
}
return text;
}
}
export enum EmojiTypeEnum {
small,
medium
}

View File

@ -22,4 +22,16 @@
background: lighten($color-primary, 5);
// -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.5);
}
}
:host ::ng-deep .emoji-small {
width: 16px;
height: 16px;
vertical-align: middle;
}
:host ::ng-deep .emoji-medium {
width: 20px;
height: 20px;
vertical-align: middle;
}