From cd1eb61e539360bc766d7aeff71b4d0ec7029138 Mon Sep 17 00:00:00 2001 From: vyneer Date: Mon, 14 Aug 2023 17:33:35 +0300 Subject: [PATCH 1/8] fix: admin messages not showing up in autocomplete --- assets/chat/js/chat.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index 817aa1d0..7924f477 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -329,9 +329,6 @@ class Chat { ) ); - this.commands - .generateAutocomplete(this.user.hasModPowers()) - .forEach((command) => this.autocomplete.add(command)); this.autocomplete.bind(this); // Chat input @@ -989,6 +986,9 @@ class Chat { onME(data) { this.setUser(data); + this.commands + .generateAutocomplete(this.user.hasModPowers()) + .forEach((command) => this.autocomplete.add(command)); if (data) { // If is a logged in user. this.loadSettings(); From 54dc7fa4aad9e84c0cab6cf7f6522a15a5c3e73e Mon Sep 17 00:00:00 2001 From: vyneer Date: Mon, 14 Aug 2023 17:33:50 +0300 Subject: [PATCH 2/8] feat: add banned phrase functionality --- assets/chat/css/style.scss | 22 +++++- assets/chat/img/tombstone.png | Bin 0 -> 10577 bytes assets/chat/js/chat.js | 81 ++++++++++++++++++++ assets/chat/js/commands.js | 26 +++++++ assets/chat/js/const.js | 5 ++ assets/chat/js/focus.js | 2 + assets/chat/js/messages/ChatDeathMessage.js | 46 +++++++++++ assets/chat/js/messages/MessageBuilder.js | 5 ++ assets/chat/js/messages/MessageTypes.js | 1 + assets/chat/js/messages/index.js | 1 + 10 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 assets/chat/img/tombstone.png create mode 100644 assets/chat/js/messages/ChatDeathMessage.js diff --git a/assets/chat/css/style.scss b/assets/chat/css/style.scss index be2ed876..09ae3c39 100644 --- a/assets/chat/css/style.scss +++ b/assets/chat/css/style.scss @@ -533,7 +533,8 @@ hr { .msg-donation, .msg-subscription, .msg-giftsub, -.msg-massgift { +.msg-massgift, +.msg-death { text-shadow: 1px 1px 3px rgba(0, 0, 0, 1); font-size: 1.1em; font-weight: 400; @@ -719,6 +720,22 @@ hr { } } +/* Death messages */ +.msg-death { + font-size: unset; + + .death-icon { + background: transparent url('../img/tombstone.png') no-repeat center center; + background-size: contain; + filter: invert(100%); + } + + .event-top, + .event-bottom { + padding: 0 $gutter-md * 2 0 $gutter-md; + } +} + /* Highlight */ .msg-highlight { color: $color-chat-text1; @@ -1849,7 +1866,8 @@ button.btn { .msg-donation, .msg-subscription, .msg-giftsub, - .msg-massgift { + .msg-massgift, + .msg-death { text-shadow: none; padding: 0; border-style: none none none solid; diff --git a/assets/chat/img/tombstone.png b/assets/chat/img/tombstone.png new file mode 100644 index 0000000000000000000000000000000000000000..a92afec2334f9db08cedd296f89e45833bdb22a7 GIT binary patch literal 10577 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 H@J{@1oVf this.onGIFTSUB(data)); this.source.on('MASSGIFT', (data) => this.onMASSGIFT(data)); this.source.on('DONATION', (data) => this.onDONATION(data)); + this.source.on('ADDPHRASE', (data) => this.onADDPHRASE(data)); + this.source.on('REMOVEPHRASE', (data) => this.onREMOVEPHRASE(data)); + this.source.on('DEATH', (data) => this.onDEATH(data)); this.control.on('SEND', (data) => this.cmdSEND(data)); this.control.on('HINT', (data) => this.cmdHINT(data)); @@ -203,6 +206,21 @@ class Chat { this.control.on('UNMOTD', () => this.cmdUNPIN()); this.control.on('HOST', (data) => this.cmdHOST(data)); this.control.on('UNHOST', () => this.cmdUNHOST()); + this.control.on('ADDPHRASE', (data) => this.cmdADDPHRASE(data)); + this.control.on('ADDBAN', (data) => this.cmdADDPHRASE(data)); + this.control.on('ADDMUTE', (data) => this.cmdADDPHRASE(data)); + this.control.on('REMOVEPHRASE', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('REMOVEBAN', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('REMOVEMUTE', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DELETEPHRASE', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DELETEBAN', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DELETEMUTE', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DPHRASE', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DBAN', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DMUTE', (data) => this.cmdREMOVEPHRASE(data)); + this.control.on('DIE', (data) => this.cmdDIE(data)); + this.control.on('SUICIDE', (data) => this.cmdDIE(data)); + this.control.on('BITLY', (data) => this.cmdDIE(data)); } setUser(user) { @@ -1269,6 +1287,33 @@ class Chat { ); } + onADDPHRASE(data) { + MessageBuilder.command(`Phrase "${data.data}" added.`, data.timestamp).into( + this + ); + } + + onREMOVEPHRASE(data) { + MessageBuilder.command( + `Phrase "${data.data}" removed.`, + data.timestamp + ).into(this); + } + + onDEATH(data) { + const user = this.users.get(data.nick) ?? new ChatUser(data.nick); + MessageBuilder.death(data.data, user, data.extradata, data.timestamp).into( + this + ); + if (user.username.toLowerCase() === data.nick.toLowerCase()) { + if (isMuteActive(data)) { + this.mutedtimer.setTimer(data.duration); + this.mutedtimer.startTimer(); + } + } + this.censor(data.nick); + } + onPRIVMSGSENT() { if (this.mainwindow.visible) { MessageBuilder.info('Your message has been sent.').into(this); @@ -2206,6 +2251,42 @@ class Chat { this.source.send('PIN', { data: '' }); } + cmdADDPHRASE(parts) { + if (!this.user.hasAnyFeatures(UserFeatures.ADMIN, UserFeatures.MODERATOR)) { + MessageBuilder.error(errorstrings.get('nopermission')).into(this); + return; + } + + if (!parts.length) { + MessageBuilder.error('No phrase provided - /addphrase ').into( + this + ); + return; + } + + this.source.send('ADDPHRASE', { data: parts.join(' ') }); + } + + cmdREMOVEPHRASE(parts) { + if (!this.user.hasAnyFeatures(UserFeatures.ADMIN, UserFeatures.MODERATOR)) { + MessageBuilder.error(errorstrings.get('nopermission')).into(this); + return; + } + + if (!parts.length) { + MessageBuilder.error('No phrase provided - /removephrase ').into( + this + ); + return; + } + + this.source.send('REMOVEPHRASE', { data: parts.join(' ') }); + } + + cmdDIE(parts) { + this.source.send('DIE', { data: parts.join(' ') }); + } + openConversation(nick) { const normalized = nick.toLowerCase(); const conv = this.whispers.get(normalized); diff --git a/assets/chat/js/commands.js b/assets/chat/js/commands.js index d32a275f..f254a6e0 100644 --- a/assets/chat/js/commands.js +++ b/assets/chat/js/commands.js @@ -15,6 +15,12 @@ const ADMIN_HELP_HEADER = 'Available admin commands: \n'; /** @type CommandList */ const CHAT_COMMANDS = [ + { + name: 'addphrase', + description: 'Add a banned phrase to chat.', + alias: ['addban', 'addmute'], + admin: true, + }, { name: 'ban', description: 'Stop from connecting to the chat.', @@ -24,6 +30,11 @@ const CHAT_COMMANDS = [ name: 'baninfo', description: 'Check your ban status.', }, + { + name: 'die', + description: 'Mute yourself for 10 minutes.', + alias: ['suicide', 'bitly'], + }, { name: 'embed', description: 'Embed a video to bigscreen.', @@ -103,6 +114,21 @@ const CHAT_COMMANDS = [ description: 'Post a video embed in chat.', alias: ['pe'], }, + { + name: 'removephrase', + description: 'Remove a banned phrase from chat.', + alias: [ + 'removeban', + 'removemute', + 'deletephrase', + 'deleteban', + 'deletemute', + 'dmute', + 'dban', + 'dphrase', + ], + admin: true, + }, { name: 'reply', description: 'Reply to the last whisper you received.', diff --git a/assets/chat/js/const.js b/assets/chat/js/const.js index fd29b5d7..e1158b36 100644 --- a/assets/chat/js/const.js +++ b/assets/chat/js/const.js @@ -79,6 +79,11 @@ const errorstrings = new Map( alreadyvoted: 'You have already voted!', nochatting: "You aren't allowed to chat. Either you haven't picked a username, or a mod disabled your privileges.", + bannedphrase: + 'Your message was filtered because it contained a banned phrase.', + duplicatephrase: 'Banned phrase already exists.', + nophrase: "Banned phrase doesn't exist.", + cantbanprotected: "Protected users can't die.", }) ); diff --git a/assets/chat/js/focus.js b/assets/chat/js/focus.js index 7466e592..862520b5 100644 --- a/assets/chat/js/focus.js +++ b/assets/chat/js/focus.js @@ -52,6 +52,7 @@ class ChatUserFocus { .msg-massgift[data-username="${value}"], .msg-massgift[data-mentioned~="${value}"], .msg-donation[data-username="${value}"], .msg-donation[data-mentioned~="${value}"], .msg-pinned[data-username="${value}"], .msg-pinned[data-mentioned~="${value}"], + .msg-death[data-username="${value}"], .msg-death[data-mentioned~="${value}"], .msg-user[data-username="${value}"], .msg-user[data-mentioned~="${value}"] { opacity:1 !important; } @@ -63,6 +64,7 @@ class ChatUserFocus { .msg-massgift[data-username="${value}"], .msg-donation[data-username="${value}"], .msg-pinned[data-username="${value}"], + .msg-death[data-username="${value}"], .msg-user[data-username="${value}"] { opacity:1 !important; } diff --git a/assets/chat/js/messages/ChatDeathMessage.js b/assets/chat/js/messages/ChatDeathMessage.js new file mode 100644 index 00000000..df8a4bbe --- /dev/null +++ b/assets/chat/js/messages/ChatDeathMessage.js @@ -0,0 +1,46 @@ +import { usernameColorFlair } from './ChatUserMessage'; +import ChatEventMessage from './ChatEventMessage'; +import MessageTypes from './MessageTypes'; + +export default class ChatDeathMessage extends ChatEventMessage { + constructor(message, user, flavorText, timestamp) { + super(message, timestamp); + this.user = user; + this.type = MessageTypes.DEATH; + this.flavorText = flavorText; + } + + html(chat = null) { + const eventTemplate = super.html(chat); + + /** @type HTMLAnchorElement */ + const user = document + .querySelector('#user-template') + ?.content.cloneNode(true).firstElementChild; + + const colorFlair = usernameColorFlair(chat.flairs, this.user); + + user.title = this.title; + user.classList.add(colorFlair?.name); + user.innerText = this.user.username; + + eventTemplate + .querySelector('.event-info') + .append(user, ` ${this.flavorText}!`); + + eventTemplate.querySelector('.event-icon').classList.add('death-icon'); + + 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 888c660f..05c9cafb 100644 --- a/assets/chat/js/messages/MessageBuilder.js +++ b/assets/chat/js/messages/MessageBuilder.js @@ -8,6 +8,7 @@ import ChatDonationMessage from './ChatDonationMessage'; import ChatRegularSubscriptionMessage from './subscriptions/ChatRegularSubscriptionMessage'; import ChatGiftedSubscriptionMessage from './subscriptions/ChatGiftedSubscriptionMessage'; import ChatMassSubscriptionMessage from './subscriptions/ChatMassSubscriptionMessage'; +import ChatDeathMessage from './ChatDeathMessage'; export default class MessageBuilder { static element(message, classes = []) { @@ -102,4 +103,8 @@ export default class MessageBuilder { static donation(message, user, currency, timestamp = null) { return new ChatDonationMessage(message, user, currency, timestamp); } + + static death(message, user, flavorText, timestamp = null) { + return new ChatDeathMessage(message, user, flavorText, timestamp); + } } diff --git a/assets/chat/js/messages/MessageTypes.js b/assets/chat/js/messages/MessageTypes.js index 312a0008..b4b8a3a9 100644 --- a/assets/chat/js/messages/MessageTypes.js +++ b/assets/chat/js/messages/MessageTypes.js @@ -13,4 +13,5 @@ export default { GIFTSUB: 'GIFTSUB', MASSGIFT: 'MASSGIFT', DONATION: 'DONATION', + DEATH: 'DEATH', }; diff --git a/assets/chat/js/messages/index.js b/assets/chat/js/messages/index.js index 4732353c..f20c76b8 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 ChatDeathMessage } from './ChatDeathMessage'; From 21aab27b720d94f0da268700c89ce230f655ef20 Mon Sep 17 00:00:00 2001 From: vyneer Date: Tue, 22 Aug 2023 15:10:25 +0300 Subject: [PATCH 3/8] feat: remove /die --- assets/chat/css/style.scss | 22 +--------- assets/chat/img/tombstone.png | Bin 10577 -> 0 bytes assets/chat/js/chat.js | 22 ---------- assets/chat/js/commands.js | 5 --- assets/chat/js/const.js | 1 - assets/chat/js/focus.js | 2 - assets/chat/js/messages/ChatDeathMessage.js | 46 -------------------- assets/chat/js/messages/MessageBuilder.js | 5 --- assets/chat/js/messages/MessageTypes.js | 1 - assets/chat/js/messages/index.js | 1 - 10 files changed, 2 insertions(+), 103 deletions(-) delete mode 100644 assets/chat/img/tombstone.png delete mode 100644 assets/chat/js/messages/ChatDeathMessage.js diff --git a/assets/chat/css/style.scss b/assets/chat/css/style.scss index 09ae3c39..be2ed876 100644 --- a/assets/chat/css/style.scss +++ b/assets/chat/css/style.scss @@ -533,8 +533,7 @@ hr { .msg-donation, .msg-subscription, .msg-giftsub, -.msg-massgift, -.msg-death { +.msg-massgift { text-shadow: 1px 1px 3px rgba(0, 0, 0, 1); font-size: 1.1em; font-weight: 400; @@ -720,22 +719,6 @@ hr { } } -/* Death messages */ -.msg-death { - font-size: unset; - - .death-icon { - background: transparent url('../img/tombstone.png') no-repeat center center; - background-size: contain; - filter: invert(100%); - } - - .event-top, - .event-bottom { - padding: 0 $gutter-md * 2 0 $gutter-md; - } -} - /* Highlight */ .msg-highlight { color: $color-chat-text1; @@ -1866,8 +1849,7 @@ button.btn { .msg-donation, .msg-subscription, .msg-giftsub, - .msg-massgift, - .msg-death { + .msg-massgift { text-shadow: none; padding: 0; border-style: none none none solid; diff --git a/assets/chat/img/tombstone.png b/assets/chat/img/tombstone.png deleted file mode 100644 index a92afec2334f9db08cedd296f89e45833bdb22a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10577 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 H@J{@1oVf this.onDONATION(data)); this.source.on('ADDPHRASE', (data) => this.onADDPHRASE(data)); this.source.on('REMOVEPHRASE', (data) => this.onREMOVEPHRASE(data)); - this.source.on('DEATH', (data) => this.onDEATH(data)); this.control.on('SEND', (data) => this.cmdSEND(data)); this.control.on('HINT', (data) => this.cmdHINT(data)); @@ -218,9 +217,6 @@ class Chat { this.control.on('DPHRASE', (data) => this.cmdREMOVEPHRASE(data)); this.control.on('DBAN', (data) => this.cmdREMOVEPHRASE(data)); this.control.on('DMUTE', (data) => this.cmdREMOVEPHRASE(data)); - this.control.on('DIE', (data) => this.cmdDIE(data)); - this.control.on('SUICIDE', (data) => this.cmdDIE(data)); - this.control.on('BITLY', (data) => this.cmdDIE(data)); } setUser(user) { @@ -1300,20 +1296,6 @@ class Chat { ).into(this); } - onDEATH(data) { - const user = this.users.get(data.nick) ?? new ChatUser(data.nick); - MessageBuilder.death(data.data, user, data.extradata, data.timestamp).into( - this - ); - if (user.username.toLowerCase() === data.nick.toLowerCase()) { - if (isMuteActive(data)) { - this.mutedtimer.setTimer(data.duration); - this.mutedtimer.startTimer(); - } - } - this.censor(data.nick); - } - onPRIVMSGSENT() { if (this.mainwindow.visible) { MessageBuilder.info('Your message has been sent.').into(this); @@ -2283,10 +2265,6 @@ class Chat { this.source.send('REMOVEPHRASE', { data: parts.join(' ') }); } - cmdDIE(parts) { - this.source.send('DIE', { data: parts.join(' ') }); - } - openConversation(nick) { const normalized = nick.toLowerCase(); const conv = this.whispers.get(normalized); diff --git a/assets/chat/js/commands.js b/assets/chat/js/commands.js index f254a6e0..edc2a193 100644 --- a/assets/chat/js/commands.js +++ b/assets/chat/js/commands.js @@ -30,11 +30,6 @@ const CHAT_COMMANDS = [ name: 'baninfo', description: 'Check your ban status.', }, - { - name: 'die', - description: 'Mute yourself for 10 minutes.', - alias: ['suicide', 'bitly'], - }, { name: 'embed', description: 'Embed a video to bigscreen.', diff --git a/assets/chat/js/const.js b/assets/chat/js/const.js index e1158b36..4a568d8c 100644 --- a/assets/chat/js/const.js +++ b/assets/chat/js/const.js @@ -83,7 +83,6 @@ const errorstrings = new Map( 'Your message was filtered because it contained a banned phrase.', duplicatephrase: 'Banned phrase already exists.', nophrase: "Banned phrase doesn't exist.", - cantbanprotected: "Protected users can't die.", }) ); diff --git a/assets/chat/js/focus.js b/assets/chat/js/focus.js index 862520b5..7466e592 100644 --- a/assets/chat/js/focus.js +++ b/assets/chat/js/focus.js @@ -52,7 +52,6 @@ class ChatUserFocus { .msg-massgift[data-username="${value}"], .msg-massgift[data-mentioned~="${value}"], .msg-donation[data-username="${value}"], .msg-donation[data-mentioned~="${value}"], .msg-pinned[data-username="${value}"], .msg-pinned[data-mentioned~="${value}"], - .msg-death[data-username="${value}"], .msg-death[data-mentioned~="${value}"], .msg-user[data-username="${value}"], .msg-user[data-mentioned~="${value}"] { opacity:1 !important; } @@ -64,7 +63,6 @@ class ChatUserFocus { .msg-massgift[data-username="${value}"], .msg-donation[data-username="${value}"], .msg-pinned[data-username="${value}"], - .msg-death[data-username="${value}"], .msg-user[data-username="${value}"] { opacity:1 !important; } diff --git a/assets/chat/js/messages/ChatDeathMessage.js b/assets/chat/js/messages/ChatDeathMessage.js deleted file mode 100644 index df8a4bbe..00000000 --- a/assets/chat/js/messages/ChatDeathMessage.js +++ /dev/null @@ -1,46 +0,0 @@ -import { usernameColorFlair } from './ChatUserMessage'; -import ChatEventMessage from './ChatEventMessage'; -import MessageTypes from './MessageTypes'; - -export default class ChatDeathMessage extends ChatEventMessage { - constructor(message, user, flavorText, timestamp) { - super(message, timestamp); - this.user = user; - this.type = MessageTypes.DEATH; - this.flavorText = flavorText; - } - - html(chat = null) { - const eventTemplate = super.html(chat); - - /** @type HTMLAnchorElement */ - const user = document - .querySelector('#user-template') - ?.content.cloneNode(true).firstElementChild; - - const colorFlair = usernameColorFlair(chat.flairs, this.user); - - user.title = this.title; - user.classList.add(colorFlair?.name); - user.innerText = this.user.username; - - eventTemplate - .querySelector('.event-info') - .append(user, ` ${this.flavorText}!`); - - eventTemplate.querySelector('.event-icon').classList.add('death-icon'); - - 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 05c9cafb..888c660f 100644 --- a/assets/chat/js/messages/MessageBuilder.js +++ b/assets/chat/js/messages/MessageBuilder.js @@ -8,7 +8,6 @@ import ChatDonationMessage from './ChatDonationMessage'; import ChatRegularSubscriptionMessage from './subscriptions/ChatRegularSubscriptionMessage'; import ChatGiftedSubscriptionMessage from './subscriptions/ChatGiftedSubscriptionMessage'; import ChatMassSubscriptionMessage from './subscriptions/ChatMassSubscriptionMessage'; -import ChatDeathMessage from './ChatDeathMessage'; export default class MessageBuilder { static element(message, classes = []) { @@ -103,8 +102,4 @@ export default class MessageBuilder { static donation(message, user, currency, timestamp = null) { return new ChatDonationMessage(message, user, currency, timestamp); } - - static death(message, user, flavorText, timestamp = null) { - return new ChatDeathMessage(message, user, flavorText, timestamp); - } } diff --git a/assets/chat/js/messages/MessageTypes.js b/assets/chat/js/messages/MessageTypes.js index b4b8a3a9..312a0008 100644 --- a/assets/chat/js/messages/MessageTypes.js +++ b/assets/chat/js/messages/MessageTypes.js @@ -13,5 +13,4 @@ export default { GIFTSUB: 'GIFTSUB', MASSGIFT: 'MASSGIFT', DONATION: 'DONATION', - DEATH: 'DEATH', }; diff --git a/assets/chat/js/messages/index.js b/assets/chat/js/messages/index.js index f20c76b8..4732353c 100644 --- a/assets/chat/js/messages/index.js +++ b/assets/chat/js/messages/index.js @@ -12,4 +12,3 @@ export { default as PinnedMessage, checkIfPinWasDismissed, } from './PinnedMessage'; -export { default as ChatDeathMessage } from './ChatDeathMessage'; From 0b72f596ebc0f11f406df4783d8d7d8a1697ab22 Mon Sep 17 00:00:00 2001 From: vyneer Date: Wed, 13 Sep 2023 19:27:09 +0300 Subject: [PATCH 4/8] feat: show which banned phrases got filtered --- assets/chat/js/chat.js | 11 +++++++++++ assets/chat/js/const.js | 2 -- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index 29d4a58e..fa5e3681 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -1203,6 +1203,17 @@ class Chat { `You are temporarily muted! You can chat again ${this.mutedtimer.getReadableDuration()}. Subscribe to remove the mute immediately.`, ); break; + case 'bannedphrase': { + const phraseCountText = + data.filtered.length === 1 + ? 'this banned phrase' + : 'these banned phrases'; + const filteredPretty = data.filtered.map((p) => `"${p}"`).join(', '); + message = MessageBuilder.error( + `Your message was filtered because it contained ${phraseCountText}: ${filteredPretty}.`, + ); + break; + } default: message = MessageBuilder.error(errorstrings.get(desc) || desc); } diff --git a/assets/chat/js/const.js b/assets/chat/js/const.js index 1a88e1af..61d52f75 100644 --- a/assets/chat/js/const.js +++ b/assets/chat/js/const.js @@ -79,8 +79,6 @@ const errorstrings = new Map( alreadyvoted: 'You have already voted!', nochatting: "You aren't allowed to chat. Either you haven't picked a username, or a mod disabled your privileges.", - bannedphrase: - 'Your message was filtered because it contained a banned phrase.', duplicatephrase: 'Banned phrase already exists.', nophrase: "Banned phrase doesn't exist.", }), From 527d38dcad75ad1542a23294fc571c1186316815 Mon Sep 17 00:00:00 2001 From: vyneer Date: Fri, 6 Oct 2023 09:46:02 +0300 Subject: [PATCH 5/8] feat: add invalid phrase error message --- assets/chat/js/const.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/chat/js/const.js b/assets/chat/js/const.js index 61d52f75..64c2d0a1 100644 --- a/assets/chat/js/const.js +++ b/assets/chat/js/const.js @@ -81,6 +81,8 @@ const errorstrings = new Map( "You aren't allowed to chat. Either you haven't picked a username, or a mod disabled your privileges.", duplicatephrase: 'Banned phrase already exists.', nophrase: "Banned phrase doesn't exist.", + invalidphrase: + 'Invalid phrase provided. Either the phrase was empty, or its regex was invalid.', }), ); From 7960530c0987b867f9aded98322bd96f64c8e23d Mon Sep 17 00:00:00 2001 From: vyneer Date: Fri, 6 Oct 2023 09:47:06 +0300 Subject: [PATCH 6/8] chore: adjust the "msg was filtered" error msg --- assets/chat/js/chat.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index fa5e3681..880a78cd 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -1204,13 +1204,8 @@ class Chat { ); break; case 'bannedphrase': { - const phraseCountText = - data.filtered.length === 1 - ? 'this banned phrase' - : 'these banned phrases'; - const filteredPretty = data.filtered.map((p) => `"${p}"`).join(', '); message = MessageBuilder.error( - `Your message was filtered because it contained ${phraseCountText}: ${filteredPretty}.`, + `Your message was filtered because it contained this banned phrase: "${data.filtered}".`, ); break; } From ad6a905a58cad0f9b2654fca39629cefc2ee982c Mon Sep 17 00:00:00 2001 From: vyneer Date: Sat, 2 Mar 2024 04:43:11 +0300 Subject: [PATCH 7/8] Revert "fix: admin messages not showing up in autocomplete" This reverts commit cd1eb61e539360bc766d7aeff71b4d0ec7029138. --- assets/chat/js/chat.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index a6f32b12..701b1e57 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -361,6 +361,9 @@ class Chat { ), ); + this.commands + .generateAutocomplete(this.user.hasModPowers()) + .forEach((command) => this.autocomplete.add(command)); this.autocomplete.bind(this); // Chat input @@ -1034,9 +1037,6 @@ class Chat { onME(data) { this.setUser(data); - this.commands - .generateAutocomplete(this.user.hasModPowers()) - .forEach((command) => this.autocomplete.add(command)); if (data) { // If is a logged in user. this.loadSettings(); From bc87f26f9eb00a523fb709bfbc893763d82cec94 Mon Sep 17 00:00:00 2001 From: vyneer Date: Sat, 2 Mar 2024 04:45:28 +0300 Subject: [PATCH 8/8] chore: change 'filtered' to 'blocked' in banned phrase error --- assets/chat/js/chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index 20bee7c9..53960cb5 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -1245,7 +1245,7 @@ class Chat { break; case 'bannedphrase': { message = MessageBuilder.error( - `Your message was filtered because it contained this banned phrase: "${data.filtered}".`, + `Your message was blocked because it contained this banned phrase: "${data.filtered}".`, ); break; }