From 1d53f6b1b659697864eaf9d73519909d57076d24 Mon Sep 17 00:00:00 2001 From: Tzahi12345 Date: Mon, 29 May 2023 21:42:13 -0400 Subject: [PATCH] Reintroduced twitch API settings Added twitch-emoticons support, began initial work of adding twitch emoticons to twitch chat --- backend/config.js | 3 ++ backend/consts.js | 12 +++++++ backend/package.json | 1 + package.json | 1 + .../twitch-chat/twitch-chat.component.html | 2 +- .../twitch-chat/twitch-chat.component.ts | 35 +++++++++++++++++-- src/app/posts.services.ts | 5 +++ src/app/settings/settings.component.html | 16 +++++++++ 8 files changed, 71 insertions(+), 4 deletions(-) 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: '{name}', + // 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 ID + + Generating an ID/secret is easy! + +
+
+ + Twitch Client Secret + + +
Use SponsorBlock API