diff --git a/src/pages/overlay/App.tsx b/src/pages/overlay/App.tsx index 87035be1..aec4038f 100644 --- a/src/pages/overlay/App.tsx +++ b/src/pages/overlay/App.tsx @@ -66,8 +66,10 @@ export default function App() { // Bind a capturing event listener for scrolling (so we can see scrolling for children) useEffect(() => { - appRef.current?.addEventListener("scroll", interacted, true) - return () => appRef.current?.removeEventListener("scroll", interacted, true) + if (!appRef.current) return + const node = appRef.current + node.addEventListener("scroll", interacted, true) + return () => node.removeEventListener("scroll", interacted, true) }, [interacted]) // Immediately sleep the overlay diff --git a/src/pages/overlay/components/ambassadorList/AmbassadorList.tsx b/src/pages/overlay/components/ambassadorList/AmbassadorList.tsx index 82931595..fc0bd22a 100644 --- a/src/pages/overlay/components/ambassadorList/AmbassadorList.tsx +++ b/src/pages/overlay/components/ambassadorList/AmbassadorList.tsx @@ -32,7 +32,7 @@ export default function AmbassadorList(props: AmbassadorListProps) { scrollListToAmbassador(ambassador.name.split(" ")[0].toLowerCase()) } } - }, [props.chatChosenAmbassador]) + }, [props.chatChosenAmbassador, ambassadors]) const scrollListToAmbassador = (name: string) => { if (!ambassadorList.current) return diff --git a/src/pages/overlay/components/overlay/Overlay.tsx b/src/pages/overlay/components/overlay/Overlay.tsx index c057555f..77a72686 100644 --- a/src/pages/overlay/components/overlay/Overlay.tsx +++ b/src/pages/overlay/components/overlay/Overlay.tsx @@ -22,6 +22,8 @@ interface OverlayProps { } export default function Overlay(props: OverlayProps) { + const { sleeping, awoken, wake, settings } = props + const [showAmbassadorList, setShowAmbassadorList] = useState(false) const chosenAmbassador = useChatCommand() const timeoutRef = useRef(undefined) @@ -29,7 +31,7 @@ export default function Overlay(props: OverlayProps) { // When a chat command is run, show the list and auto-dismiss it after 6s useEffect(() => { - if (chosenAmbassador !== undefined && !props.settings.disableChatPopup) { + if (chosenAmbassador !== undefined && !settings.disableChatPopup) { // Show the list, and dismiss it after 6s setShowAmbassadorList(true) timeoutRef.current = setTimeout(() => { setShowAmbassadorList(false) }, 6000) @@ -38,13 +40,13 @@ export default function Overlay(props: OverlayProps) { awakingRef.current = true // Wake the overlay for 8s - props.wake(8000) + wake(8000) } return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current) } - }, [chosenAmbassador, props.wake]) + }, [chosenAmbassador, settings.disableChatPopup, wake]) // If the user interacts with the overlay, clear the auto-dismiss timer useEffect(() => { @@ -52,12 +54,12 @@ export default function Overlay(props: OverlayProps) { if (awakingRef.current) awakingRef.current = false else if (timeoutRef.current) clearTimeout(timeoutRef.current) } - props.awoken.add(callback) - return () => props.awoken.remove(callback) - }, [props.awoken]) + awoken.add(callback) + return () => awoken.remove(callback) + }, [awoken]) return ( -
+
setShowAmbassadorList(!showAmbassadorList)} /> diff --git a/src/utils/chatCommand.ts b/src/utils/chatCommand.ts index fa38cb69..dba04bdd 100644 --- a/src/utils/chatCommand.ts +++ b/src/utils/chatCommand.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import tmi, { ChatUserstate } from 'tmi.js' import AmbassadorData from '../assets/ambassadors.json' @@ -32,11 +32,10 @@ const getMapOfAmbassadorWithDiacritics = (): Map => { export default function useChatCommand() { const [command, setCommand] = useState() - const ambassadorNames = AmbassadorData.map((ambassador) => ambassador.name.split(' ')[0].toLowerCase()) + const [ambassadorNames] = useState(AmbassadorData.map((ambassador) => ambassador.name.split(' ')[0].toLowerCase())) + const [diacriticsMap] = useState>(getMapOfAmbassadorWithDiacritics()) - const diacriticsMap: Map = getMapOfAmbassadorWithDiacritics() - - const client = new tmi.Client({ + const [client] = useState(new tmi.Client({ connection: { secure: true, reconnect: true @@ -46,15 +45,9 @@ export default function useChatCommand() { 'Maya', 'AlveusSanctuary' ] - }) - - useEffect(() => { - client.on('message', messageHandler) - client.on('connected', connectedHandler) - client.connect() - }, []) + })) - const messageHandler = (channel: string, tags: ChatUserstate, msg: string, self: boolean) => { + const messageHandler = useCallback((channel: string, tags: ChatUserstate, msg: string, self: boolean) => { //ignore if user is not a moderator or broadcaster or if the user is not AbdullahMorrison if (!tags.mod && !tags.badges?.broadcaster && tags.username !== 'abdullahmorrison') return // Ignore echoed messages (messages sent by the bot) and messages that don't start with '!' @@ -66,10 +59,17 @@ export default function useChatCommand() { } else if (diacriticsMap.get(commandName.slice(1))) { // Check if a user typed a name without diacritics (Ex: !jalapeno should be !JalapeƱo) setCommand("!"+diacriticsMap.get(commandName.slice(1))) } - } - const connectedHandler = () => { + }, [ambassadorNames, diacriticsMap]) + + const connectedHandler = useCallback(() => { console.log('*Twitch extension is connected to chat*') - } + }, []) + + useEffect(() => { + client.on('message', messageHandler) + client.on('connected', connectedHandler) + client.connect() + }, [client, messageHandler, connectedHandler]) return command }