From f649c59ff167c97e48888e3518e2551940769fb0 Mon Sep 17 00:00:00 2001 From: Anatole Date: Mon, 9 Aug 2021 14:58:00 +0200 Subject: [PATCH 1/2] Reset cursor on space press & add space at end --- src/Content/Runtime/TabCompleteDetection.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Content/Runtime/TabCompleteDetection.tsx b/src/Content/Runtime/TabCompleteDetection.tsx index c3ab95f36..cdc2b17d5 100644 --- a/src/Content/Runtime/TabCompleteDetection.tsx +++ b/src/Content/Runtime/TabCompleteDetection.tsx @@ -37,7 +37,13 @@ export class TabCompleteDetection { } this.handleTabPress(ev, foundEmotes); - } else if (resetKeycodes.includes(ev.code)) { // Reset the cursor when the user is done typing an emote + } else if (resetKeycodes.includes(ev.key)) { // Reset the cursor when the user is done typing an emote + // Remove the last character + // Unless the user is selecting many characters + if (this.tab.cursor.length > 0 && input.selectionStart === input.selectionEnd) { + this.app.sendMessageDown('SetChatInput', input.value.slice(0, input.value.length - 1)); + } + this.resetCursor(); } }; @@ -100,7 +106,7 @@ export class TabCompleteDetection { // Request the pagescript to modify the input const final = currentWord ?? ''; const lastOccurence = input.value.lastIndexOf(final); - this.app.sendMessageDown('SetChatInput', input.value.slice(0, lastOccurence) + input.value.slice(lastOccurence).replace(final, next)); + this.app.sendMessageDown('SetChatInput', (input.value.slice(0, lastOccurence) + input.value.slice(lastOccurence).replace(final, next + ' ')).slice(0, 500)); } } @@ -108,6 +114,6 @@ const startsWith = (prefix: string, emoteName: string): boolean => emoteName.toLowerCase().startsWith(prefix.toLowerCase()); const resetKeycodes = [ - 'Space', 'Backspace', 'Enter', + ' ', 'Backspace', 'Enter', 'Delete' ]; From a782b140e90f7890db94b35483fdf29613d6f371 Mon Sep 17 00:00:00 2001 From: Anatole Date: Mon, 9 Aug 2021 15:56:33 +0200 Subject: [PATCH 2/2] Support twitch emotes --- src/Content/App/App.tsx | 30 ++++++++++++++++++++ src/Content/Runtime/TabCompleteDetection.tsx | 2 +- src/Global/EmoteStore.tsx | 5 ++++ src/Page/Runtime/ChatListener.ts | 6 ++++ src/Page/Util/Twitch.ts | 26 +++++++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/Content/App/App.tsx b/src/Content/App/App.tsx index 48b833ee2..96970f377 100644 --- a/src/Content/App/App.tsx +++ b/src/Content/App/App.tsx @@ -15,6 +15,7 @@ import { TabCompleteDetection } from 'src/Content/Runtime/TabCompleteDetection'; import { DataStructure } from '@typings/typings/DataStructure'; import { Badge } from 'src/Global/Badge'; import { ExtensionContentScript } from 'src/Content/Content'; +import { Constants } from '@typings/src/Constants'; @Child export class App implements Child.OnInjected, Child.OnAppLoaded { @@ -190,6 +191,35 @@ export class App implements Child.OnInjected, Child.OnAppLoaded { onChatScroll.next(undefined); } + /** + * Receive twitch emotes from the page layer and create our emote sets for them, + * @param emoteSets the twitch emote sets + */ + @PageScriptListener('ReceiveTwitchEmotes') + whenWhenTwitchEmotesWhenEmotesTwitchOkayge(emoteSets: Twitch.TwitchEmoteSet[]): void { + // Iterate through sets, and start adding to our twitch set + const emotes = [] as DataStructure.Emote[]; + for (const twset of emoteSets) { + for (const emote of twset.emotes) { + emotes.push({ + id: emote.id, + name: emote.token, + visibility: 0, + provider: 'TWITCH', + status: Constants.Emotes.Status.LIVE, + tags: [], + owner: !!twset.owner ? { + id: twset.owner.id, + display_name: twset.owner.displayName, + login: twset.owner.login + } as DataStructure.TwitchUser : undefined + }); + } + } + + emoteStore.enableSet(`twitch`, emotes); + } + /** * Synchronize the emote sets with the pagescript */ diff --git a/src/Content/Runtime/TabCompleteDetection.tsx b/src/Content/Runtime/TabCompleteDetection.tsx index cdc2b17d5..dbfcd6bac 100644 --- a/src/Content/Runtime/TabCompleteDetection.tsx +++ b/src/Content/Runtime/TabCompleteDetection.tsx @@ -19,7 +19,7 @@ export class TabCompleteDetection { } updateEmotes(): void { - this.emotes = this.app.emoteStore.getAllEmotes(['7TV', 'BTTV', 'FFZ']); + this.emotes = this.app.emoteStore.getAllEmotes(['7TV', 'BTTV', 'FFZ', 'TWITCH']).sort((a, b) => a.name.localeCompare(b.name)); } /** diff --git a/src/Global/EmoteStore.tsx b/src/Global/EmoteStore.tsx index 9a9d38fd6..5edebfff5 100644 --- a/src/Global/EmoteStore.tsx +++ b/src/Global/EmoteStore.tsx @@ -58,6 +58,11 @@ export class EmoteStore { } const set = this.sets.get(TWITCH_SET_NAME) as EmoteStore.EmoteSet; + const currentEmote = set.getEmoteByID(data.emoteID ?? ''); + if (!!currentEmote) { + return currentEmote; + } + set.push([{ id: data.emoteID ?? '', name: data.alt, diff --git a/src/Page/Runtime/ChatListener.ts b/src/Page/Runtime/ChatListener.ts index c37b11436..319762d0d 100644 --- a/src/Page/Runtime/ChatListener.ts +++ b/src/Page/Runtime/ChatListener.ts @@ -83,6 +83,12 @@ export class ChatListener { } }); + // Send twitch emotes to upper layer + const twitchEmotes = this.twitch.getChat()?.props.emotes; + if (Array.isArray(twitchEmotes)) { + this.page.sendMessageUp('ReceiveTwitchEmotes', twitchEmotes); + } + /** * OBSERVE THE DOM AND GET ADDED COMPONENTS */ diff --git a/src/Page/Util/Twitch.ts b/src/Page/Util/Twitch.ts index 4f057520d..248a7f928 100644 --- a/src/Page/Util/Twitch.ts +++ b/src/Page/Util/Twitch.ts @@ -309,6 +309,7 @@ export namespace Twitch { chatRoomHeader: any; chatRules: string[]; chatView: number; + emotes: TwitchEmoteSet[]; location: { hash: string; pathname: string; @@ -322,6 +323,31 @@ export namespace Twitch { chatListElement: HTMLDivElement; }>; + export interface TwitchEmoteSet { + id: string; + emotes: TwitchEmote[]; + owner?: { + displayName: string; + id: string; + login: string; + profileImageURL: string; + }; + } + + export interface TwitchEmote { + id: string; + modifiers: any; + setID: string; + token: string; + type: string; + owner?: { + displayName: string; + id: string; + login: string; + profileImageURL: string; + }; + } + export interface BadgeSets { channelsBySet: Map>; count: number;