Skip to content

Commit

Permalink
feat: twitch chat hook
Browse files Browse the repository at this point in the history
  • Loading branch information
6lr61 committed Sep 11, 2024
1 parent 37415ba commit 4dd2ef9
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 3 deletions.
93 changes: 93 additions & 0 deletions src/hooks/useTwitchChat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { useCallback, useContext, useEffect, useState } from "react";
import { AuthStateContext } from "../contexts/auth-state/AuthStateContext";
import type { ChatMessageEvent } from "../utils/event-sub/events/chat/message";
import { EventSubContext } from "../contexts/event-sub/EventSubContext";
import type { ChatEventCommon } from "../utils/event-sub/events/chat/_common";
import type { ChatClearUserMessageEvent } from "../utils/event-sub/events/chat/clearUser";
import type { ChatMessageDeleteEvent } from "../utils/event-sub/events/chat/messageDelete";

type ChatEvent =
| ChatMessage
| ({ type: "channel.chat.clear" } & ChatEventCommon)
| ({ type: "channel.chat.clear_user_messages" } & ChatClearUserMessageEvent)
| ({ type: "channel.chat.message_delete" } & ChatMessageDeleteEvent);

type ChatMessage = {
type: "channel.chat.message";
} & ChatMessageEvent;

const subscriptions = [
"channel.chat.clear",
"channel.chat.clear_user_messages",
"channel.chat.message",
"channel.chat.message_delete",
];

export function useTwitchChat(bufferSize = 50, channelId?: string) {
const authStateContext = useContext(AuthStateContext);
const eventSubContext = useContext(EventSubContext);
const [messages, setMessages] = useState<ChatMessage[]>([]);

if (!authStateContext) {
throw new Error("useTwitchChat: Needs an AuthStateContext Provider!");
}

if (!eventSubContext) {
throw new Error("useTwitchChat: Needs a EventSubContext Provider!");
}

const { subscribe } = eventSubContext;

const handleMessage = useCallback(
(event: Record<string, unknown>) => {
const messageEvent = event as unknown as ChatEvent; // FIXME!

switch (messageEvent.type) {
case "channel.chat.clear":
setMessages(() => []);
break;
case "channel.chat.clear_user_messages":
setMessages((messages) =>
messages.filter(
(message) =>
message.chatter_user_id !== messageEvent.target_user_id
)
);
break;
case "channel.chat.message_delete":
setMessages((messages) =>
messages.filter(
(message) => message.message_id !== messageEvent.message_id
)
);
break;
case "channel.chat.message":
setMessages((messages) => [
...messages.slice(-bufferSize + 1),
messageEvent,
]);
break;
default:
console.error("useTwitchChat: Called with unknown event:", event);
}
},
[bufferSize]
);

useEffect(() => {
const { authState } = authStateContext;

if (!authState) {
return;
}

const condition = {
broadcaster_user_id: channelId ?? authState.user.id,
user_id: authState.user.id,
};

return subscribe(authState, subscriptions, condition, handleMessage);
}, [authStateContext, channelId, handleMessage, subscribe]);

return messages;
}
2 changes: 1 addition & 1 deletion src/utils/event-sub/events/chat/clearUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface ChatClearUserMessagePayload {
event: ChatClearUserMessageEvent;
}

interface ChatClearUserMessageEvent extends ChatEventCommon {
export interface ChatClearUserMessageEvent extends ChatEventCommon {
target_user_id: string;
target_user_name: string;
target_user_login: string;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/event-sub/events/chat/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface ChatMessagePayload {
event: ChatMessageEvent;
}

interface ChatMessageEvent extends ChatEventCommon {
export interface ChatMessageEvent extends ChatEventCommon {
chatter_user_id: string;
chatter_user_name: string;
chatter_user_login: string;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/event-sub/events/chat/messageDelete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface ChatMessageDeletePayload {
event: ChatMessageDeleteEvent;
}

interface ChatMessageDeleteEvent extends ChatEventCommon {
export interface ChatMessageDeleteEvent extends ChatEventCommon {
target_user_id: string;
target_user_name: string;
target_user_login: string;
Expand Down

0 comments on commit 4dd2ef9

Please sign in to comment.