diff --git a/src/renderer/src/providers/ChatProvider.jsx b/src/renderer/src/providers/ChatProvider.jsx index 5b48457..f27fc14 100644 --- a/src/renderer/src/providers/ChatProvider.jsx +++ b/src/renderer/src/providers/ChatProvider.jsx @@ -1908,6 +1908,12 @@ const useChatStore = create((set, get) => ({ useCosmeticsStore?.getState()?.addUserStyle(transformedUsername, body); break; } + case "entitlement.delete": { + const username = body?.object?.user?.connections?.find((c) => c.platform === "KICK")?.username; + const transformedUsername = username?.replaceAll("-", "_").toLowerCase(); + useCosmeticsStore?.getState()?.removeUserStyle(transformedUsername, body); + break; + } default: break; } diff --git a/src/renderer/src/providers/CosmeticsProvider.jsx b/src/renderer/src/providers/CosmeticsProvider.jsx index 9f064fa..609a576 100644 --- a/src/renderer/src/providers/CosmeticsProvider.jsx +++ b/src/renderer/src/providers/CosmeticsProvider.jsx @@ -35,6 +35,50 @@ const useCosmeticsStore = create((set, get) => ({ }); }, + removeUserStyle: (username, body) => { + if (!username) return; + const transformedUsername = username.toLowerCase(); + const refId = body?.object?.ref_id; + const kind = body?.object?.kind; + + if (!refId || !kind) return; + + set((state) => { + const currentStyle = state.userStyles[transformedUsername]; + if (!currentStyle) return state; + + // Remove by kind and ref_id + let updatedStyle = { ...currentStyle }; + let hasChanges = false; + + if (kind === "BADGE" && currentStyle.badgeId === refId) { + updatedStyle.badgeId = null; + hasChanges = true; + } else if (kind === "PAINT" && currentStyle.paintId === refId) { + updatedStyle.paintId = null; + hasChanges = true; + } + + if (!hasChanges) return state; + + // If both badge and paint are removed, remove the entire user style entry + if (!updatedStyle.badgeId && !updatedStyle.paintId) { + const { [transformedUsername]: removed, ...restUserStyles } = state.userStyles; + return { userStyles: restUserStyles }; + } + + return { + userStyles: { + ...state.userStyles, + [transformedUsername]: { + ...updatedStyle, + updatedAt: new Date().toISOString(), + }, + }, + }; + }); + }, + getUserStyle: (username) => { if (!username) return null; const transformedUsername = username.toLowerCase(); diff --git a/utils/services/connectionManager.js b/utils/services/connectionManager.js index ff70288..3284d52 100644 --- a/utils/services/connectionManager.js +++ b/utils/services/connectionManager.js @@ -306,7 +306,7 @@ class ConnectionManager { span.addEvent('7tv_websocket_add_start'); this.stvWebSocket.addChatroom( chatroom.id, - chatroom.streamerData.id, // Use the Kick channel ID for cosmetic/entitlement subscriptions + chatroom.streamerData.user_id, // Use the correct Kick user ID for cosmetic/entitlement subscriptions stvId, stvEmoteSetId ); @@ -586,7 +586,7 @@ class ConnectionManager { this.stvWebSocket.addChatroom( chatroom.id, - chatroom.streamerData?.id, + chatroom.streamerData?.user_id, stvId, stvEmoteSetId, ); diff --git a/utils/services/seventv/sharedStvWebSocket.js b/utils/services/seventv/sharedStvWebSocket.js index 387ba23..e0ede3d 100644 --- a/utils/services/seventv/sharedStvWebSocket.js +++ b/utils/services/seventv/sharedStvWebSocket.js @@ -615,12 +615,13 @@ class SharedStvWebSocket extends EventTarget { break; case "entitlement.create": + case "entitlement.delete": if (body.kind === 10) { this.dispatchEvent( new CustomEvent("message", { detail: { body, - type: "entitlement.create", + type: type, // Use the actual event type (create or delete) chatroomId, }, }),