Skip to content

Commit

Permalink
Update emotes without having to refresh chat.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mitchdev committed Oct 28, 2023
1 parent 3050349 commit 333fbe2
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 16 deletions.
1 change: 1 addition & 0 deletions assets/chat/css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ hr {
}
}

.msg-genevent,
.msg-donation,
.msg-subscription,
.msg-giftsub,
Expand Down
10 changes: 10 additions & 0 deletions assets/chat/js/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ class ChatAutoComplete {
}
}

removeEmotes() {
this.buckets.forEach((bucket, key) => {
if (key !== '/') {
bucket.forEach((ac, str) => {
if (ac.isemote) bucket.delete(str);
});
}
});
}

select(index) {
this.selected = Math.min(index, this.results.length - 1);
const result = this.results[this.selected];
Expand Down
90 changes: 79 additions & 11 deletions assets/chat/js/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import makeSafeForRegex, {
import { HashLinkConverter, MISSING_ARG_ERROR } from './hashlinkconverter';
import ChatCommands from './commands';
import MessageTemplateHTML from '../../views/templates.html';
import { EmoteFormatter } from './formatters';

class Chat {
constructor(config) {
Expand Down Expand Up @@ -85,6 +86,7 @@ class Chat {
this.flairs = [];
this.flairsMap = new Map();
this.emoteService = new EmoteService();
this.emoteformatter = new EmoteFormatter();

this.user = new ChatUser();
this.users = new Map();
Expand Down Expand Up @@ -141,6 +143,10 @@ class Chat {
this.source.on('MASSGIFT', (data) => this.onMASSGIFT(data));
this.source.on('DONATION', (data) => this.onDONATION(data));
this.source.on('UPDATEUSER', (data) => this.onUPDATEUSER(data));
this.source.on('THEMECHANGED', (data) => this.onTHEMECHANGED(data));
this.source.on('EMOTECHANGED', (data) => this.onEMOTECHANGED(data));
this.source.on('EMOTEADDED', (data) => this.onEMOTEADDED(data));
this.source.on('EMOTEREMOVED', (data) => this.onEMOTEREMOVED(data));

this.control.on('SEND', (data) => this.cmdSEND(data));
this.control.on('HINT', (data) => this.cmdHINT(data));
Expand Down Expand Up @@ -503,18 +509,35 @@ class Chat {
await this.loadFlairs();
}

async loadEmotes() {
async reloadEmotes(cacheKey, updateMessages = true) {
this.config.cacheKey = cacheKey;
await this.loadEmotes();

if (updateMessages) {
for (const window of this.windows.values()) {
window.updateMessages(this, true);
}
}
}

async loadEmotes(cssOnly = false) {
const emotecss = document.getElementById('emotescss');
if (emotecss) emotecss.remove();
Chat.loadCss(
`${this.config.cdn.base}/emotes/emotes.css?_=${this.config.cacheKey}`,
'emotescss',
);
return fetch(
`${this.config.cdn.base}/emotes/emotes.json?_=${this.config.cacheKey}`,
)
.then((res) => res.json())
.then((json) => {
this.setEmotes(json);
})
.catch(() => {});
if (!cssOnly) {
return fetch(
`${this.config.cdn.base}/emotes/emotes.json?_=${this.config.cacheKey}`,
)
.then((res) => res.json())
.then((json) => {
this.setEmotes(json);
})
.catch(() => {});
}
return null;
}

async loadFlairs() {
Expand Down Expand Up @@ -561,6 +584,7 @@ class Chat {

setEmotes(emotes) {
this.emoteService.setEmotes(emotes);
this.autocomplete.removeEmotes();
this.emoteService
.emotesForUser(this.user)
.map((e) => e.prefix)
Expand Down Expand Up @@ -1399,6 +1423,49 @@ class Chat {
}
}

onTHEMECHANGED(data) {
this.reloadEmotes(data.cacheKey);

MessageBuilder.event({
infoHtml: `Theme changed to ${data.label}`,
borderColor: data.color,
}).into(this);
}

async onEMOTECHANGED(data) {
await this.reloadEmotes(data.cacheKey);

// Only send a message if prefix changed.
if (data.oldEmote.prefix !== data.newEmote.prefix) {
MessageBuilder.event({
infoHtml: `${data.oldEmote.prefix} was changed to ${
data.newEmote.prefix
} ${this.emoteformatter.format(this, data.newEmote.prefix)}`,
}).into(this);
}
}

async onEMOTEADDED(data) {
await this.reloadEmotes(data.cacheKey, false);

MessageBuilder.event({
infoHtml: `${data.emote.prefix} was added ${this.emoteformatter.format(
this,
data.emote.prefix,
)}`,
borderColor: 'success',
}).into(this);
}

onEMOTEREMOVED(data) {
this.reloadEmotes(data.cacheKey);

MessageBuilder.event({
infoHtml: `${data.prefix} was removed`,
borderColor: 'fail',
}).into(this);
}

cmdSHOWPOLL() {
if (this.chatpoll.poll) {
this.chatpoll.show();
Expand Down Expand Up @@ -2303,7 +2370,7 @@ class Chat {
}

static removeSlashCmdFromText(msg) {
return msg.replace(regexslashcmd, '').trim();
return msg ? msg.replace(regexslashcmd, '').trim() : '';
}

static extractNicks(text) {
Expand Down Expand Up @@ -2368,12 +2435,13 @@ class Chat {
return nanoseconds;
}

static loadCss(url) {
static loadCss(url, id) {
const link = document.createElement('link');
link.href = url;
link.type = 'text/css';
link.rel = 'stylesheet';
link.media = 'screen';
if (id) link.id = id;
document.getElementsByTagName('head')[0].appendChild(link);
return link;
}
Expand Down
11 changes: 8 additions & 3 deletions assets/chat/js/emotes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default class EmoteService {
tiers = new Set();
emoteTiers = new Set();

emotesMapped = new Map();

Expand Down Expand Up @@ -41,17 +41,22 @@ export default class EmoteService {
return this.emotes.filter((e) => e.twitch).map((e) => e.prefix);
}

get tiers() {
return Array.from(this.emoteTiers).sort((a, b) => a - b);
}

getEmote(emote) {
return this.emotesMapped.get(emote);
}

setEmotes(emotes) {
this.emoteTiers = new Set();
this.emotesMapped = new Map();
this.emotes = emotes;
emotes.forEach((e) => {
this.tiers.add(e.minimumSubTier);
this.emoteTiers.add(e.minimumSubTier);
this.emotesMapped.set(e.prefix, e);
});
this.tiers = Array.from(this.tiers).sort((a, b) => a - b);
}

emotePrefixesForTier(tier) {
Expand Down
50 changes: 50 additions & 0 deletions assets/chat/js/messages/ChatGenericEventMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import ChatEventMessage from './ChatEventMessage';
import MessageTypes from './MessageTypes';

/*
UPDATE TO TYPESCRIPT
options {
infoHtml: string,
bottomText: string,
borderColor: 'success' | 'fail' | 'info' | 'css color'
}
*/

function getBorderColor(color) {
switch (color) {
case 'success':
return '#61bd4f'; // $color-green
case 'danger':
case 'fail':
return '#eb5a46'; // $color-red
case 'info':
return '#ffab4a'; // $color-orange
default:
return color;
}
}

export default class ChatGenericEventMessage extends ChatEventMessage {
constructor(options) {
super(options.bottomText, options.timestamp);
this.type = MessageTypes.GENEVENT;
this.options = options;
}

html(chat = null) {
const eventTemplate = super.html(chat);

eventTemplate.querySelector('.event-info').innerHTML =
this.options.infoHtml ?? '';

const attr = {};
if (this.options.borderColor) {
attr.style = `border-color: ${getBorderColor(this.options.borderColor)}`;
}

return this.wrap(eventTemplate.innerHTML, [], attr);
}
}
5 changes: 5 additions & 0 deletions assets/chat/js/messages/ChatMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export default class ChatMessage extends ChatUIMessage {
);
}

rebuildTxt(chat) {
const text = this.buildMessageTxt(chat);
this.ui.getElementsByClassName('text')[0].outerHTML = text;
}

buildMessageTxt(chat) {
// TODO we strip off the `/me ` of every message -- must be a better way to do this
let msg =
Expand Down
5 changes: 5 additions & 0 deletions assets/chat/js/messages/MessageBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ChatDonationMessage from './ChatDonationMessage';
import ChatRegularSubscriptionMessage from './subscriptions/ChatRegularSubscriptionMessage';
import ChatGiftedSubscriptionMessage from './subscriptions/ChatGiftedSubscriptionMessage';
import ChatMassSubscriptionMessage from './subscriptions/ChatMassSubscriptionMessage';
import ChatGenericEventMessage from './ChatGenericEventMessage';

export default class MessageBuilder {
static element(message, classes = []) {
Expand Down Expand Up @@ -60,6 +61,10 @@ export default class MessageBuilder {
return new PinnedMessage(message, user, timestamp, uuid);
}

static event(options) {
return new ChatGenericEventMessage(options);
}

static subscription(data) {
return new ChatRegularSubscriptionMessage(
data.data,
Expand Down
1 change: 1 addition & 0 deletions assets/chat/js/messages/MessageTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export default {
GIFTSUB: 'GIFTSUB',
MASSGIFT: 'MASSGIFT',
DONATION: 'DONATION',
GENEVENT: 'GENEVENT',
};
1 change: 1 addition & 0 deletions assets/chat/js/messages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export { default as ChatUserMessage } from './ChatUserMessage';
export { default as ChatGiftedSubscriptionMessage } from './subscriptions/ChatGiftedSubscriptionMessage';
export { default as ChatMassSubscriptionMessage } from './subscriptions/ChatMassSubscriptionMessage';
export { default as ChatRegularSubscriptionMessage } from './subscriptions/ChatRegularSubscriptionMessage';
export { default as ChatGenericEventMessage } from './ChatGenericEventMessage';
export {
default as PinnedMessage,
checkIfPinWasDismissed,
Expand Down
6 changes: 5 additions & 1 deletion assets/chat/js/window.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class ChatWindow extends EventEmitter {
* Use chat state (settings and authentication data) to update the messages in
* this window.
*/
updateMessages(chat) {
updateMessages(chat, rebuildTxt = false) {
for (const message of this.messages) {
if (message.type !== MessageTypes.UI) {
message.updateTimeFormat();
Expand All @@ -136,6 +136,10 @@ class ChatWindow extends EventEmitter {
message.setTag(chat.taggednicks.get(username));
message.setTagTitle(chat.taggednotes.get(username));

if (rebuildTxt) {
message.rebuildTxt(chat);
}

if (message.moderated) {
message.censor(parseInt(chat.settings.get('showremoved') || '1', 10));
}
Expand Down
2 changes: 1 addition & 1 deletion assets/views/templates.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div>
<div class="event-wrapper">
<div class="event-top">
<span class="event-info"></span>
<span class="event-info text"></span>
<i class="event-icon"></i>
</div>
<div class="event-bottom"></div>
Expand Down

0 comments on commit 333fbe2

Please sign in to comment.