diff --git a/assets/chat/css/style.scss b/assets/chat/css/style.scss index 6cc58035..97ffb9e3 100644 --- a/assets/chat/css/style.scss +++ b/assets/chat/css/style.scss @@ -535,23 +535,11 @@ hr { } } -/* Broadcasts */ -.msg-broadcast { - background-color: $color-chat-emphasize; - color: $color-text-broadcast !important; - font-size: 1.1em; - font-weight: 400; - padding-top: $gutter-md; - padding-bottom: $gutter-md; - time { - margin-right: $gutter-md; - } -} - .msg-donation, .msg-subscription, .msg-giftsub, -.msg-massgift { +.msg-massgift, +.msg-broadcast { text-shadow: 1px 1px 3px rgba(0, 0, 0, 1); font-size: 1.1em; font-weight: 400; @@ -614,6 +602,18 @@ hr { } } +/* Broadcasts */ +.msg-broadcast { + border-color: $color-text-broadcast; + + .broadcast-icon { + background: transparent url('../img/icon-broadcast.png') no-repeat center + center; + background-size: contain; + filter: invert(100%); + } +} + /* Donations */ .msg-donation { .donation-icon { diff --git a/assets/chat/img/icon-broadcast.png b/assets/chat/img/icon-broadcast.png new file mode 100644 index 00000000..1ab16b82 Binary files /dev/null and b/assets/chat/img/icon-broadcast.png differ diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index 81a40d04..6cd52644 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -1257,12 +1257,17 @@ class Chat { if (!this.backlogloading) { const retryMilli = Math.floor(Math.random() * 30000) + 4000; setTimeout(() => window.location.reload(true), retryMilli); + MessageBuilder.broadcast( - `Restart incoming in ${Math.round(retryMilli / 1000)} seconds ...`, + `Restart incoming in ${Math.round(retryMilli / 1000)} seconds...`, + new ChatUser(), + data.timestamp, ).into(this); } } else { - MessageBuilder.broadcast(data.data, data.timestamp).into(this); + const user = + this.users.get(data.nick.toLowerCase()) ?? new ChatUser(data.user); + MessageBuilder.broadcast(data.data, user, data.timestamp).into(this); } } diff --git a/assets/chat/js/messages/ChatBroadcastMessage.js b/assets/chat/js/messages/ChatBroadcastMessage.js new file mode 100644 index 00000000..6b358e01 --- /dev/null +++ b/assets/chat/js/messages/ChatBroadcastMessage.js @@ -0,0 +1,58 @@ +import { usernameColorFlair } from './ChatUserMessage'; +import ChatEventMessage from './ChatEventMessage'; +import MessageTypes from './MessageTypes'; + +export default class ChatBroadcastMessage extends ChatEventMessage { + constructor(message, user, timestamp = null) { + super(message, timestamp); + this.type = MessageTypes.BROADCAST; + this.user = user; + } + + buildUserTemplate(chat = null) { + if (this.user.displayName !== '') { + const colorFlair = usernameColorFlair(chat.flairs, this.user); + + /** @type HTMLAnchorElement */ + const user = document + .querySelector('#user-template') + ?.content.cloneNode(true).firstElementChild; + user.title = this.title; + user.classList.add(colorFlair?.name); + user.innerText = this.user.displayName; + + const ctrl = document.createElement('span'); + ctrl.innerText = ': '; + + return [user, ctrl]; + } + + return []; + } + + html(chat = null) { + const eventTemplate = super.html(chat); + + const text = eventTemplate.querySelector('.event-bottom')?.innerHTML; + eventTemplate.querySelector('.event-bottom').remove(); + eventTemplate.querySelector('.event-info').innerHTML = text; + + const user = this.buildUserTemplate(chat); + + eventTemplate.querySelector('.event-icon').classList.add('broadcast-icon'); + eventTemplate.querySelector('.event-info').prepend(...user); + + const classes = Array.from(eventTemplate.classList); + const attributes = eventTemplate + .getAttributeNames() + .reduce((object, attributeName) => { + if (attributeName === 'class') return object; + return { + ...object, + [attributeName]: eventTemplate.getAttribute(attributeName), + }; + }, {}); + + return this.wrap(eventTemplate.innerHTML, classes, attributes); + } +} diff --git a/assets/chat/js/messages/MessageBuilder.js b/assets/chat/js/messages/MessageBuilder.js index 4baf7f93..8f908143 100644 --- a/assets/chat/js/messages/MessageBuilder.js +++ b/assets/chat/js/messages/MessageBuilder.js @@ -9,6 +9,7 @@ import ChatDonationMessage from './ChatDonationMessage'; import ChatRegularSubscriptionMessage from './subscriptions/ChatRegularSubscriptionMessage'; import ChatGiftedSubscriptionMessage from './subscriptions/ChatGiftedSubscriptionMessage'; import ChatMassSubscriptionMessage from './subscriptions/ChatMassSubscriptionMessage'; +import ChatBroadcastMessage from './ChatBroadcastMessage'; export default class MessageBuilder { static element(message, classes = []) { @@ -27,8 +28,8 @@ export default class MessageBuilder { return new ChatMessage(message, timestamp, MessageTypes.INFO); } - static broadcast(message, timestamp = null) { - return new ChatMessage(message, timestamp, MessageTypes.BROADCAST); + static broadcast(message, user, timestamp = null) { + return new ChatBroadcastMessage(message, user, timestamp); } static command(message, timestamp = null) { diff --git a/assets/chat/js/messages/index.js b/assets/chat/js/messages/index.js index 4732353c..c7bfbbed 100644 --- a/assets/chat/js/messages/index.js +++ b/assets/chat/js/messages/index.js @@ -12,3 +12,4 @@ export { default as PinnedMessage, checkIfPinWasDismissed, } from './PinnedMessage'; +export { default as ChatBroadcastMessage } from './ChatBroadcastMessage'; diff --git a/assets/chat/js/user.js b/assets/chat/js/user.js index fe6987b5..b7b5628c 100644 --- a/assets/chat/js/user.js +++ b/assets/chat/js/user.js @@ -53,12 +53,12 @@ class ChatUser { this.displayName = user; this.username = this.displayName.toLowerCase(); } else { - this.id = user.id || null; - this.displayName = user.nick || ''; + this.id = user?.id || null; + this.displayName = user?.nick || ''; this.username = this.displayName.toLowerCase(); - this.createdDate = user.createdDate || ''; - this.features = user.features || []; - this.watching = user.watching || null; + this.createdDate = user?.createdDate || ''; + this.features = user?.features || []; + this.watching = user?.watching || null; } }