Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/Content/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
*/
Expand Down
14 changes: 10 additions & 4 deletions src/Content/Runtime/TabCompleteDetection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

/**
Expand All @@ -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();
}
};
Expand Down Expand Up @@ -100,14 +106,14 @@ 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));
}
}

const startsWith = (prefix: string, emoteName: string): boolean =>
emoteName.toLowerCase().startsWith(prefix.toLowerCase());

const resetKeycodes = [
'Space', 'Backspace', 'Enter',
' ', 'Backspace', 'Enter',
'Delete'
];
5 changes: 5 additions & 0 deletions src/Global/EmoteStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions src/Page/Runtime/ChatListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
26 changes: 26 additions & 0 deletions src/Page/Util/Twitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ export namespace Twitch {
chatRoomHeader: any;
chatRules: string[];
chatView: number;
emotes: TwitchEmoteSet[];
location: {
hash: string;
pathname: string;
Expand All @@ -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<string, Map<string, ChatBadge>>;
count: number;
Expand Down