diff --git a/client/src/twitchTypes.ts b/client/src/twitchTypes.ts index 2bd713a6..e3162087 100644 --- a/client/src/twitchTypes.ts +++ b/client/src/twitchTypes.ts @@ -75,7 +75,8 @@ type MessageId = | 'raid' | 'unraid' | 'ritual' - | 'bitsbadgetier'; + | 'bitsbadgetier' + | 'gigantified-emote-message'; type CommonTags = { 'badge-info': BadgeInfo; @@ -105,7 +106,6 @@ export type UserStateTags = { }; export type NoticeTags = { - 'msg-id': string | 'resub'; 'target-user-id': string; }; diff --git a/client/src/views/Chat/Chat.less b/client/src/views/Chat/Chat.less index 67a4529c..6cd3d12a 100644 --- a/client/src/views/Chat/Chat.less +++ b/client/src/views/Chat/Chat.less @@ -67,6 +67,12 @@ background: linear-gradient(90deg, rgb(190, 54, 236), rgb(7, 55, 176)); } + &-gigantified>span>span.chat-message-text>img:last-of-type { + width: 112px; + height: 112px; + max-height: unset; + } + &-thick-text-shadow { text-shadow: rgb(0, 0, 0) 2px 0px 0px, rgb(0, 0, 0) 1.75517px 0.958851px 0px, rgb(0, 0, 0) 1.0806px 1.68294px 0px, rgb(0, 0, 0) 0.141474px 1.99499px 0px, rgb(0, 0, 0) -0.832294px 1.81859px 0px, rgb(0, 0, 0) -1.60229px 1.19694px 0px, rgb(0, 0, 0) -1.97998px 0.28224px 0px, rgb(0, 0, 0) -1.87291px -0.701566px 0px, rgb(0, 0, 0) -1.30729px -1.5136px 0px, rgb(0, 0, 0) -0.421592px -1.95506px 0px, rgb(0, 0, 0) 0.567324px -1.91785px 0px, rgb(0, 0, 0) 1.41734px -1.41108px 0px, rgb(0, 0, 0) 1.92034px -0.558831px 0px; } diff --git a/client/src/views/Chat/ChatEntry.tsx b/client/src/views/Chat/ChatEntry.tsx index 34662d7e..7e3cd5c1 100644 --- a/client/src/views/Chat/ChatEntry.tsx +++ b/client/src/views/Chat/ChatEntry.tsx @@ -36,6 +36,7 @@ export const ChatEntry = ({ }: ChatEntryProps) => { const selectedDisplayName = useStore((s) => s.selectedDisplayName); const color = chatMessage.parsedMessage.tags.color; + const gigantified = chatMessage.parsedMessage.tags['msg-id'] === 'gigantified-emote-message'; const actionMessage = chatMessage.parsedMessage.command.botCommand === 'ACTION'; const message = chatMessage.parsedMessage.command.botCommand === 'ACTION' @@ -61,6 +62,7 @@ export const ChatEntry = ({ showBorders && chatMessage.parsedMessage.tags.subscriber === '1' && 'chat-message-body-subscriber', chatMessage.isSpotlighted && 'chat-message-body-spotlighted', dropShadowEnabled && thickTextShadowEnabled && 'chat-message-body-thick-text-shadow', + gigantified && 'chat-message-body-gigantified', )} style={{ ...(dropShadowEnabled && !thickTextShadowEnabled diff --git a/client/src/views/Chat/ChatImageRenderer.tsx b/client/src/views/Chat/ChatImageRenderer.tsx index 632ea899..8159de7a 100644 --- a/client/src/views/Chat/ChatImageRenderer.tsx +++ b/client/src/views/Chat/ChatImageRenderer.tsx @@ -38,8 +38,7 @@ export const ChatImageRenderer = ({ const emoteName = message.slice(Number(positioning[0].startPosition - offset), Number(positioning[0].endPosition - offset) + 1); twitchEmoteMap[emoteName] = { origin: 'twitch', - src: `https://static-cdn.jtvnw.net/emoticons/v2/${emoteUrlPart}/default/dark/1.0`, - srcSet: `https://static-cdn.jtvnw.net/emoticons/v2/${emoteUrlPart}/default/dark/1.0 1x, https://static-cdn.jtvnw.net/emoticons/v2/${emoteUrlPart}/default/dark/2.0 2x, https://static-cdn.jtvnw.net/emoticons/v2/${emoteUrlPart}/default/dark/3.0 4x`, + src: `https://static-cdn.jtvnw.net/emoticons/v2/${emoteUrlPart}/default/dark/3.0`, width: null, height: null, modifier: false, diff --git a/server/src/handlers/twitch/irc/parsers/parseTags.test.ts b/server/src/handlers/twitch/irc/parsers/parseTags.test.ts index ec828e1e..35cbf860 100644 --- a/server/src/handlers/twitch/irc/parsers/parseTags.test.ts +++ b/server/src/handlers/twitch/irc/parsers/parseTags.test.ts @@ -79,6 +79,14 @@ describe('parseTags', () => { expect(parsedMessage?.command?.botCommandParams).toEqual('does a thing'); }); }); + describe('giantified emote PRIVMSG test message', () => { + const message = + '@badge-info=subscriber/38;badges=broadcaster/1,subscriber/12,game-developer/1;color=#5052B2;display-name=Athano;emotes=166266:3-11/emotesv2_ec84debaec7c4bd8a50a3d532541c60a:14-24;first-msg=0;flags=;id=f1c01f0b-52fe-4c59-b7eb-05f2b373f791;mod=0;msg-id=gigantified-emote-message;returning-chatter=0;room-id=30458956;subscriber=1;tmi-sent-ts=1725469180476;turbo=0;user-id=30458956;user-type= :athano!athano@athano.tmi.twitch.tv PRIVMSG #athano :hi CarlSmile athanoBongo'; + const parsedMessage = parseMessage(message); + test('should have msg-id property', () => { + expect(parsedMessage?.tags?.['msg-id']).toEqual('gigantified-emote-message'); + }); + }); describe('first NOTICE test message', () => { const message = '@msg-id=delete_message_success :tmi.twitch.tv NOTICE #bar :The message from foo is now deleted.'; const parsedMessage = parseMessage(message); diff --git a/server/src/types.ts b/server/src/types.ts index 698c3065..899b37d4 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -102,7 +102,8 @@ type MessageId = | 'raid' | 'unraid' | 'ritual' - | 'bitsbadgetier'; + | 'bitsbadgetier' + | 'gigantified-emote-message'; type CommonTags = { 'badge-info': BadgeInfo; @@ -146,6 +147,7 @@ export type PrivMsgTags = CommonTags & { 'reply-parent-msg-body': string; // The text of the parent message. The message does not include this tag if this message is not a reply. 'first-msg': StringBoolean; vip: StringBoolean; // A Boolean value that determines whether the user that sent the chat is a VIP. The message includes this tag if the user is a VIP; otherwise, the message doesn’t include this tag (check for the presence of the tag instead of whether the tag is set to true or false). + 'msg-id': MessageId; }; export type RoomstateTags = {