mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-04-18 15:31:28 +03:00
Reintroduced twitch API settings
Added twitch-emoticons support, began initial work of adding twitch emoticons to twitch chat
This commit is contained in:
@@ -208,6 +208,9 @@ const DEFAULT_CONFIG = {
|
|||||||
"API_key": "",
|
"API_key": "",
|
||||||
"use_youtube_API": false,
|
"use_youtube_API": false,
|
||||||
"youtube_API_key": "",
|
"youtube_API_key": "",
|
||||||
|
"use_twitch_API": false,
|
||||||
|
"twitch_client_ID": "",
|
||||||
|
"twitch_client_secret": "",
|
||||||
"twitch_auto_download_chat": false,
|
"twitch_auto_download_chat": false,
|
||||||
"use_sponsorblock_API": false,
|
"use_sponsorblock_API": false,
|
||||||
"generate_NFO_files": false,
|
"generate_NFO_files": false,
|
||||||
|
|||||||
@@ -110,6 +110,18 @@ exports.CONFIG_ITEMS = {
|
|||||||
'key': 'ytdl_youtube_api_key',
|
'key': 'ytdl_youtube_api_key',
|
||||||
'path': 'YoutubeDLMaterial.API.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': {
|
'ytdl_twitch_auto_download_chat': {
|
||||||
'key': 'ytdl_twitch_auto_download_chat',
|
'key': 'ytdl_twitch_auto_download_chat',
|
||||||
'path': 'YoutubeDLMaterial.API.twitch_auto_download_chat'
|
'path': 'YoutubeDLMaterial.API.twitch_auto_download_chat'
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/builders": "^1.6.1",
|
"@discordjs/builders": "^1.6.1",
|
||||||
"@discordjs/core": "^0.5.2",
|
"@discordjs/core": "^0.5.2",
|
||||||
|
"@tzahi12345/twitch-emoticons": "^1.0.3",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^5.3.1",
|
||||||
"async": "^3.2.3",
|
"async": "^3.2.3",
|
||||||
"async-mutex": "^0.4.0",
|
"async-mutex": "^0.4.0",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"@angular/router": "^15.0.1",
|
"@angular/router": "^15.0.1",
|
||||||
"@fontsource/material-icons": "^4.5.4",
|
"@fontsource/material-icons": "^4.5.4",
|
||||||
"@ngneat/content-loader": "^7.0.0",
|
"@ngneat/content-loader": "^7.0.0",
|
||||||
|
"@tzahi12345/twitch-emoticons": "^1.0.3",
|
||||||
"@videogular/ngx-videogular": "^6.0.0",
|
"@videogular/ngx-videogular": "^6.0.0",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="chat-container" #scrollContainer *ngIf="visible_chat">
|
<div class="chat-container" #scrollContainer *ngIf="visible_chat">
|
||||||
<div style="width: 250px; text-align: center;"><strong>Twitch Chat</strong></div>
|
<div style="width: 250px; text-align: center;"><strong>Twitch Chat</strong></div>
|
||||||
<div #chat style="max-width: 250px" *ngFor="let chat of visible_chat; let last = last">
|
<div #chat style="max-width: 250px" *ngFor="let chat of visible_chat; let last = last">
|
||||||
{{chat.timestamp_str}} - <strong [style.color]="chat.user_color ? chat.user_color : null">{{chat.name}}</strong>: {{chat.message}}
|
{{chat.timestamp_str}} - <strong [style.color]="chat.user_color ? chat.user_color : null">{{chat.name}}</strong>: <span [innerHTML]="chat.message"></span>
|
||||||
{{last ? scrollToBottom() : ''}}
|
{{last ? scrollToBottom() : ''}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Component, ElementRef, Input, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
import { Component, ElementRef, Input, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
||||||
import { DatabaseFile } from 'api-types';
|
import { DatabaseFile } from 'api-types';
|
||||||
import { PostsService } from 'app/posts.services';
|
import { PostsService } from 'app/posts.services';
|
||||||
|
import { EmoteFetcher, EmoteJSON, EmoteParser } from '@tzahi12345/twitch-emoticons';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-twitch-chat',
|
selector: 'app-twitch-chat',
|
||||||
@@ -21,6 +22,9 @@ export class TwitchChatComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
scrollContainer = null;
|
scrollContainer = null;
|
||||||
|
|
||||||
|
fetcher: EmoteFetcher;
|
||||||
|
parser: EmoteParser;
|
||||||
|
|
||||||
@Input() db_file: DatabaseFile = null;
|
@Input() db_file: DatabaseFile = null;
|
||||||
@Input() sub = null;
|
@Input() sub = null;
|
||||||
@Input() current_timestamp = 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;
|
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++) {
|
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) {
|
const new_chat = this.full_chat[i];
|
||||||
this.visible_chat.push(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;
|
this.current_chat_index = i;
|
||||||
} else if (this.full_chat[i]['timestamp'] > this.current_timestamp) {
|
} else if (new_chat['timestamp'] > this.current_timestamp) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,6 +124,29 @@ export class TwitchChatComponent implements OnInit, OnDestroy {
|
|||||||
this.chat_check_interval_obj = setInterval(() => this.addNewChatMessages(), this.CHAT_CHECK_INTERVAL_MS);
|
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: '<img class="emote" alt="{name}" src="{link}">',
|
||||||
|
// 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) {
|
function binarySearch(arr, key, n) {
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ import {
|
|||||||
import { isoLangs } from './dialogs/user-profile-dialog/locales_list';
|
import { isoLangs } from './dialogs/user-profile-dialog/locales_list';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { MatDrawerMode } from '@angular/material/sidenav';
|
import { MatDrawerMode } from '@angular/material/sidenav';
|
||||||
|
import type { EmoteJSON } from '@tzahi12345/twitch-emoticons';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PostsService implements CanActivate {
|
export class PostsService implements CanActivate {
|
||||||
@@ -407,6 +408,10 @@ export class PostsService implements CanActivate {
|
|||||||
return this.http.post<DownloadTwitchChatByVODIDResponse>(this.path + 'downloadTwitchChatByVODID', body, this.httpOptions);
|
return this.http.post<DownloadTwitchChatByVODIDResponse>(this.path + 'downloadTwitchChatByVODID', body, this.httpOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTwitchEmotes() {
|
||||||
|
return this.http.post<{emotes: EmoteJSON[]}>(this.path + 'getTwitchEmotes', {}, this.httpOptions);
|
||||||
|
}
|
||||||
|
|
||||||
downloadPlaylistFromServer(playlist_id, uuid = null) {
|
downloadPlaylistFromServer(playlist_id, uuid = null) {
|
||||||
const body: DownloadFileRequest = {uuid: uuid, playlist_id: playlist_id};
|
const body: DownloadFileRequest = {uuid: uuid, playlist_id: playlist_id};
|
||||||
return this.http.post(this.path + 'downloadFileFromServer', body, {responseType: 'blob', params: this.httpOptions.params});
|
return this.http.post(this.path + 'downloadFileFromServer', body, {responseType: 'blob', params: this.httpOptions.params});
|
||||||
|
|||||||
@@ -252,9 +252,25 @@
|
|||||||
<mat-hint><a target="_blank" href="https://developers.google.com/youtube/v3/getting-started"><ng-container i18n="Youtube API Key setting hint">Generating a key is easy!</ng-container></a></mat-hint>
|
<mat-hint><a target="_blank" href="https://developers.google.com/youtube/v3/getting-started"><ng-container i18n="Youtube API Key setting hint">Generating a key is easy!</ng-container></a></mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['use_twitch_API']"><ng-container i18n="Use Twitch API setting">Use Twitch API</ng-container></mat-checkbox>
|
||||||
|
</div>
|
||||||
<div class="col-12 mt-1">
|
<div class="col-12 mt-1">
|
||||||
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['twitch_auto_download_chat']"><ng-container i18n="Auto download Twitch Chat setting">Auto-download Twitch Chat</ng-container></mat-checkbox>
|
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['twitch_auto_download_chat']"><ng-container i18n="Auto download Twitch Chat setting">Auto-download Twitch Chat</ng-container></mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<mat-form-field class="text-field" color="accent">
|
||||||
|
<mat-label i18n="Twitch Client ID">Twitch Client ID</mat-label>
|
||||||
|
<input [disabled]="!new_config['API']['use_twitch_API']" [(ngModel)]="new_config['API']['twitch_client_ID']" matInput required>
|
||||||
|
<mat-hint><a target="_blank" href="https://dev.twitch.tv/docs/api/"><ng-container i18n="Twitch Client ID setting hint">Generating an ID/secret is easy!</ng-container></a></mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 mt-2">
|
||||||
|
<mat-form-field class="text-field" color="accent">
|
||||||
|
<mat-label i18n="Twitch Client Secret">Twitch Client Secret</mat-label>
|
||||||
|
<input [disabled]="!new_config['API']['use_twitch_API']" [(ngModel)]="new_config['API']['twitch_client_secret']" matInput required>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
<div class="col-12 mt-2">
|
<div class="col-12 mt-2">
|
||||||
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['use_sponsorblock_API']" matTooltip="Enables a button to skip ads when viewing supported videos." i18n-matTooltip="SponsorBlock API tooltip"><ng-container i18n="Use SponsorBlock API setting">Use SponsorBlock API</ng-container></mat-checkbox>
|
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['use_sponsorblock_API']" matTooltip="Enables a button to skip ads when viewing supported videos." i18n-matTooltip="SponsorBlock API tooltip"><ng-container i18n="Use SponsorBlock API setting">Use SponsorBlock API</ng-container></mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user