diff --git a/backend/config.js b/backend/config.js
index a5ee5df..683b776 100644
--- a/backend/config.js
+++ b/backend/config.js
@@ -208,6 +208,9 @@ const DEFAULT_CONFIG = {
"API_key": "",
"use_youtube_API": false,
"youtube_API_key": "",
+ "use_twitch_API": false,
+ "twitch_client_ID": "",
+ "twitch_client_secret": "",
"twitch_auto_download_chat": false,
"use_sponsorblock_API": false,
"generate_NFO_files": false,
diff --git a/backend/consts.js b/backend/consts.js
index e121dad..57f170a 100644
--- a/backend/consts.js
+++ b/backend/consts.js
@@ -110,6 +110,18 @@ exports.CONFIG_ITEMS = {
'key': 'ytdl_youtube_api_key',
'path': 'YoutubeDLMaterial.API.youtube_API_key'
},
+ 'ytdl_use_twitch_api': {
+ 'key': 'ytdl_use_twitch_api',
+ 'path': 'YoutubeDLMaterial.API.use_twitch_API'
+ },
+ 'ytdl_twitch_client_id': {
+ 'key': 'ytdl_twitch_client_id',
+ 'path': 'YoutubeDLMaterial.API.twitch_client_ID'
+ },
+ 'ytdl_twitch_client_secret': {
+ 'key': 'ytdl_twitch_client_secret',
+ 'path': 'YoutubeDLMaterial.API.twitch_client_secret'
+ },
'ytdl_twitch_auto_download_chat': {
'key': 'ytdl_twitch_auto_download_chat',
'path': 'YoutubeDLMaterial.API.twitch_auto_download_chat'
diff --git a/backend/package.json b/backend/package.json
index 11f0e92..f27614f 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -25,6 +25,7 @@
"dependencies": {
"@discordjs/builders": "^1.6.1",
"@discordjs/core": "^0.5.2",
+ "@tzahi12345/twitch-emoticons": "^1.0.3",
"archiver": "^5.3.1",
"async": "^3.2.3",
"async-mutex": "^0.4.0",
diff --git a/package.json b/package.json
index c34d535..6825725 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"@angular/router": "^15.0.1",
"@fontsource/material-icons": "^4.5.4",
"@ngneat/content-loader": "^7.0.0",
+ "@tzahi12345/twitch-emoticons": "^1.0.3",
"@videogular/ngx-videogular": "^6.0.0",
"core-js": "^2.4.1",
"crypto-js": "^4.1.1",
diff --git a/src/app/components/twitch-chat/twitch-chat.component.html b/src/app/components/twitch-chat/twitch-chat.component.html
index 43fbac0..376682d 100644
--- a/src/app/components/twitch-chat/twitch-chat.component.html
+++ b/src/app/components/twitch-chat/twitch-chat.component.html
@@ -1,7 +1,7 @@
Twitch Chat
- {{chat.timestamp_str}} - {{chat.name}}: {{chat.message}}
+ {{chat.timestamp_str}} - {{chat.name}}:
{{last ? scrollToBottom() : ''}}
diff --git a/src/app/components/twitch-chat/twitch-chat.component.ts b/src/app/components/twitch-chat/twitch-chat.component.ts
index 88ccdf5..04a44b3 100644
--- a/src/app/components/twitch-chat/twitch-chat.component.ts
+++ b/src/app/components/twitch-chat/twitch-chat.component.ts
@@ -1,6 +1,7 @@
import { Component, ElementRef, Input, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { DatabaseFile } from 'api-types';
import { PostsService } from 'app/posts.services';
+import { EmoteFetcher, EmoteJSON, EmoteParser } from '@tzahi12345/twitch-emoticons';
@Component({
selector: 'app-twitch-chat',
@@ -21,6 +22,9 @@ export class TwitchChatComponent implements OnInit, OnDestroy {
scrollContainer = null;
+ fetcher: EmoteFetcher;
+ parser: EmoteParser;
+
@Input() db_file: DatabaseFile = null;
@Input() sub = null;
@Input() current_timestamp = null;
@@ -69,10 +73,12 @@ export class TwitchChatComponent implements OnInit, OnDestroy {
const latest_chat_timestamp = this.visible_chat.length ? this.visible_chat[this.visible_chat.length - 1]['timestamp'] : 0;
for (let i = this.current_chat_index + 1; i < this.full_chat.length; i++) {
- if (this.full_chat[i]['timestamp'] >= latest_chat_timestamp && this.full_chat[i]['timestamp'] <= this.current_timestamp) {
- this.visible_chat.push(this.full_chat[i]);
+ const new_chat = this.full_chat[i];
+ if (new_chat['timestamp'] >= latest_chat_timestamp && new_chat['timestamp'] <= this.current_timestamp) {
+ new_chat['message'] = this.parseChat(new_chat['message']);
+ this.visible_chat.push(new_chat);
this.current_chat_index = i;
- } else if (this.full_chat[i]['timestamp'] > this.current_timestamp) {
+ } else if (new_chat['timestamp'] > this.current_timestamp) {
break;
}
}
@@ -118,6 +124,29 @@ export class TwitchChatComponent implements OnInit, OnDestroy {
this.chat_check_interval_obj = setInterval(() => this.addNewChatMessages(), this.CHAT_CHECK_INTERVAL_MS);
}
+ getEmotes() {
+ this.postsService.getTwitchEmotes().subscribe(res => {
+ const emotes = res['emotes'];
+ this.processEmotes(emotes);
+ });
+ }
+
+ processEmotes(emotes: EmoteJSON[]) {
+ this.fetcher = new EmoteFetcher();
+ this.parser = new EmoteParser(this.fetcher, {
+ // Custom HTML format
+ template: '
',
+ // Match without :colons:
+ match: /(\w+)+?/g
+ });
+
+ this.fetcher.fromJSON(emotes);
+ }
+
+ parseChat(chat_message: string) {
+ return this.parser.parse(chat_message);
+ }
+
}
function binarySearch(arr, key, n) {
diff --git a/src/app/posts.services.ts b/src/app/posts.services.ts
index 67f86e3..22c3019 100644
--- a/src/app/posts.services.ts
+++ b/src/app/posts.services.ts
@@ -118,6 +118,7 @@ import {
import { isoLangs } from './dialogs/user-profile-dialog/locales_list';
import { Title } from '@angular/platform-browser';
import { MatDrawerMode } from '@angular/material/sidenav';
+import type { EmoteJSON } from '@tzahi12345/twitch-emoticons';
@Injectable()
export class PostsService implements CanActivate {
@@ -407,6 +408,10 @@ export class PostsService implements CanActivate {
return this.http.post(this.path + 'downloadTwitchChatByVODID', body, this.httpOptions);
}
+ getTwitchEmotes() {
+ return this.http.post<{emotes: EmoteJSON[]}>(this.path + 'getTwitchEmotes', {}, this.httpOptions);
+ }
+
downloadPlaylistFromServer(playlist_id, uuid = null) {
const body: DownloadFileRequest = {uuid: uuid, playlist_id: playlist_id};
return this.http.post(this.path + 'downloadFileFromServer', body, {responseType: 'blob', params: this.httpOptions.params});
diff --git a/src/app/settings/settings.component.html b/src/app/settings/settings.component.html
index 6d4ae4d..8358599 100644
--- a/src/app/settings/settings.component.html
+++ b/src/app/settings/settings.component.html
@@ -252,9 +252,25 @@
Generating a key is easy!
+
+ Use Twitch API
+
Auto-download Twitch Chat
+
+
+
+ Twitch Client Secret
+
+
+
Use SponsorBlock API