diff --git a/src/components/DonatersTopList/DonatersTopList.tsx b/src/components/DonatersTopList/DonatersTopList.tsx index bba4de5..5b21cbf 100644 --- a/src/components/DonatersTopList/DonatersTopList.tsx +++ b/src/components/DonatersTopList/DonatersTopList.tsx @@ -4,7 +4,7 @@ import axios from "axios"; import "./DonatersTopList.css"; import { useLoaderData, useNavigate } from "react-router"; import { findSetting } from "../utils"; -import { setupCommandListener, subscribe } from "../../socket"; +import { cleanupCommandListener, setupCommandListener, subscribe, unsubscribe } from "../../socket"; import FontImport from "../FontImport/FontImport"; const overflowHiddenForRootElement = ( @@ -73,6 +73,10 @@ export default function DonatersTopList({}: {}) { }); setupCommandListener(widgetId, () => navigate(0)); updateDonaters(); + return () => { + unsubscribe(widgetId, conf.topic.alerts); + cleanupCommandListener(widgetId); + }; }, [recipientId]); const type = findSetting(settings, "type", "All"); diff --git a/src/components/DonationGoal/DonationGoal.tsx b/src/components/DonationGoal/DonationGoal.tsx index 3214f19..0131182 100644 --- a/src/components/DonationGoal/DonationGoal.tsx +++ b/src/components/DonationGoal/DonationGoal.tsx @@ -1,7 +1,12 @@ import React, { useEffect, useRef, useState } from "react"; import { useLoaderData, useNavigate } from "react-router"; import { WidgetData } from "../../types/WidgetData"; -import { setupCommandListener, subscribe } from "../../socket"; +import { + cleanupCommandListener, + setupCommandListener, + subscribe, + unsubscribe, +} from "../../socket"; import { log } from "../../logging"; import classes from "./DonationGoal.module.css"; import { findSetting } from "../utils"; @@ -23,6 +28,10 @@ export default function DonationGoal({}) { navigate(0); }); setupCommandListener(widgetId, () => navigate(0)); + return () => { + unsubscribe(widgetId, conf.topic.goal); + cleanupCommandListener(widgetId); + }; }, [recipientId]); useEffect(() => { @@ -63,9 +72,6 @@ export default function DonationGoal({}) { }; const filledColor = findSetting(settings, "filledColor", "green"); - const filledStyle = { - backgroundColor: filledColor, - }; const filledTextColor = findSetting(settings, "filledTextColor", "white"); const filledFontSize = findSetting(settings, "filledFontSize", "24"); const filledFont = findSetting(settings, "font", "Russo One"); @@ -86,17 +92,16 @@ export default function DonationGoal({}) { {goal.briefDescription}
diff --git a/src/components/DonationTimer/DonationTimer.tsx b/src/components/DonationTimer/DonationTimer.tsx index db2b17c..3b72483 100644 --- a/src/components/DonationTimer/DonationTimer.tsx +++ b/src/components/DonationTimer/DonationTimer.tsx @@ -4,12 +4,13 @@ import axios from "axios"; import "./DonationTimer.css"; import { useLoaderData, useNavigate } from "react-router"; import { findSetting } from "../utils"; -import { setupCommandListener, subscribe } from "../../socket"; +import { cleanupCommandListener, setupCommandListener, subscribe, unsubscribe } from "../../socket"; import FontImport from "../FontImport/FontImport"; import { log } from "../../logging"; +import { WidgetData } from "../../types/WidgetData"; export default function DonationTimer({}: {}) { - const { recipientId, settings, conf, widgetId } = useLoaderData(); + const { recipientId, settings, conf, widgetId } = useLoaderData() as WidgetData; const navigate = useNavigate(); const [lastDonationTime, setLastDonationTime] = useState(null); const [time, setTime] = useState(""); @@ -22,6 +23,10 @@ export default function DonationTimer({}: {}) { message.ack(); }); setupCommandListener(widgetId, () => navigate(0)); + return () => { + unsubscribe(widgetId, conf.topic.alerts); + cleanupCommandListener(widgetId); + }; }, [recipientId]); useEffect(() => { diff --git a/src/components/MediaWidget/MediaWidget.tsx b/src/components/MediaWidget/MediaWidget.tsx index 702ac75..b08bb14 100644 --- a/src/components/MediaWidget/MediaWidget.tsx +++ b/src/components/MediaWidget/MediaWidget.tsx @@ -4,7 +4,7 @@ import "bootstrap/dist/css/bootstrap.min.css"; import { useLoaderData, useNavigate } from "react-router"; import "./MediaWidget.css"; import { PlaylistController } from "./PlaylistController"; -import { publish, setupCommandListener } from "../../socket"; +import { cleanupCommandListener, publish, setupCommandListener } from "../../socket"; import Menu from "../Menu/Menu"; import { PaymentPageConfig } from "./PaymentPageConfig"; import RequestsDisabledWarning from "./RequestsDisabledWarning"; @@ -65,6 +65,9 @@ export default function MediaWidget({}: {}) { }, playlistController: playlistController.current, }); + return () => { + cleanupCommandListener(widgetId); + }; }, [recipientId, widgetId]); useEffect(() => { diff --git a/src/components/MediaWidget/VideoJSComponent.tsx b/src/components/MediaWidget/VideoJSComponent.tsx index 7d07750..b8cef3c 100644 --- a/src/components/MediaWidget/VideoJSComponent.tsx +++ b/src/components/MediaWidget/VideoJSComponent.tsx @@ -112,7 +112,7 @@ export default function VideoJSComponent({ useEffect(() => { subscribe(widgetId, conf.topic.playerCommands, (message) => { - log.debug(`message: ${JSON.stringify(message)}`); + log.debug({message: message}, "Received player command"); if (commandHandler.current) { commandHandler.current(message); } diff --git a/src/components/PaymentAlerts/PaymentAlerts.tsx b/src/components/PaymentAlerts/PaymentAlerts.tsx index 8d3c046..8d09ab8 100644 --- a/src/components/PaymentAlerts/PaymentAlerts.tsx +++ b/src/components/PaymentAlerts/PaymentAlerts.tsx @@ -3,7 +3,7 @@ import classes from "./PaymentAlerts.module.css"; import { useLoaderData, useNavigate } from "react-router"; import "bootstrap/dist/css/bootstrap.min.css"; import { log } from "../../logging"; -import { setupCommandListener, subscribe } from "../../socket"; +import { cleanupCommandListener, setupCommandListener, subscribe, unsubscribe } from "../../socket"; import { AlertController } from "../../logic/alert/AlertController"; import MessageBody from "./sections/MessageBody"; import MessageTitle from "./sections/MessageTitle"; @@ -41,6 +41,10 @@ function PaymentAlerts({}: {}) { message.ack(); }); setupCommandListener(widgetId, () => navigate(0)); + return () => { + unsubscribe(widgetId, conf.topic.alertWidgetCommans); + cleanupCommandListener(widgetId); + } }, [widgetId]); return ( diff --git a/src/components/Payments/Payments.tsx b/src/components/Payments/Payments.tsx index 49418f4..fe4f295 100644 --- a/src/components/Payments/Payments.tsx +++ b/src/components/Payments/Payments.tsx @@ -6,7 +6,7 @@ import "bootstrap/dist/css/bootstrap.min.css"; import axios from "axios"; import Menu from "../Menu/Menu"; import { findSetting } from "../utils"; -import { publish, setupCommandListener, subscribe } from "../../socket"; +import { cleanupCommandListener, publish, setupCommandListener, subscribe, unsubscribe } from "../../socket"; import { log } from "../../logging"; import TestAlertPopup from "../TestAlertPopup/TestAlertPopup"; import MenuEventButton from "../Menu/MenuEventButton"; @@ -55,6 +55,11 @@ function Payments({}: {}) { message.ack(); }); setupCommandListener(widgetId, () => navigate(0)); + return () => { + unsubscribe(widgetId, conf.topic.alertStatus); + unsubscribe(widgetId, conf.topic.alerts); + cleanupCommandListener(widgetId); + }; }, [recipientId]); function setDisplayedTimeForTodayPayments(todayPayments) { diff --git a/src/components/PlayerInfo/PlayerInfo.tsx b/src/components/PlayerInfo/PlayerInfo.tsx index 9f3d3e2..adccad6 100644 --- a/src/components/PlayerInfo/PlayerInfo.tsx +++ b/src/components/PlayerInfo/PlayerInfo.tsx @@ -4,7 +4,7 @@ import { useState } from "react"; import "bootstrap/dist/css/bootstrap.min.css"; import { useLoaderData, useNavigate } from "react-router"; import { findSetting } from "../utils"; -import { setupCommandListener, subscribe } from "../../socket"; +import { cleanupCommandListener, setupCommandListener, subscribe, unsubscribe } from "../../socket"; import { log } from "../../logging"; import FontImport from "../FontImport/FontImport"; @@ -27,6 +27,10 @@ function PlayerInfo() { message.ack(); }); setupCommandListener(widgetId, () => navigate(0)); + return () => { + unsubscribe(widgetId, conf.topic.player); + cleanupCommandListener(widgetId); + }; }, [widgetId]); const fontSize = findSetting(settings, "fontSize", "24px"); diff --git a/src/pages/Reel/ReelWidget.module.css b/src/pages/Reel/ReelWidget.module.css index 45199e8..423c981 100644 --- a/src/pages/Reel/ReelWidget.module.css +++ b/src/pages/Reel/ReelWidget.module.css @@ -1,10 +1,17 @@ .reelitem { - border: 1px solid; text-align: center; padding-top: 20px; padding-bottom: 20px; font-size: 30px; + height: min-content; +} + +.reelitemcontainer { + border: 1px solid; border-radius: 20px; + display: flex; + flex-direction: column; + justify-content: space-around; } .active { diff --git a/src/pages/Reel/ReelWidget.tsx b/src/pages/Reel/ReelWidget.tsx index cc51056..5f696c7 100644 --- a/src/pages/Reel/ReelWidget.tsx +++ b/src/pages/Reel/ReelWidget.tsx @@ -4,7 +4,12 @@ import "@glidejs/glide/dist/css/glide.theme.min.css"; import React, { useEffect, useRef, useState } from "react"; import { useLoaderData, useNavigate } from "react-router-dom"; -import { setupCommandListener, subscribe } from "../../socket"; +import { + cleanupCommandListener, + setupCommandListener, + subscribe, + unsubscribe, +} from "../../socket"; import classes from "./ReelWidget.module.css"; import { log } from "../../logging"; import { findSetting } from "../../components/utils"; @@ -18,28 +23,32 @@ export default function ReelWidget({}) { const [active, setActive] = useState(null); const [highlight, setHighlight] = useState(false); - function handleSelection(selection: string){ - if (!glideRef.current?.classList.contains("hidden")) { - setTimeout(() => handleSelection(selection), 40000); - return; - } - setActive(selection); - setTimeout(() => { - log.debug(`clear active and highlight`); - setActive(null); - setHighlight(false); - glideRef.current?.classList.add("hidden"); - }, 20000); + function handleSelection(selection: string) { + if (!glideRef.current?.classList.contains("hidden")) { + setTimeout(() => handleSelection(selection), 40000); + return; + } + setActive(selection); + setTimeout(() => { + log.debug(`clear active and highlight`); + setActive(null); + setHighlight(false); + glideRef.current?.classList.add("hidden"); + }, 20000); } useEffect(() => { subscribe(widgetId, conf.topic.reel, (message) => { - log.info(`Received reel command: ${message.body}`); + log.info({ message: message }, "Received reel command"); let json = JSON.parse(message.body); handleSelection(json.selection); message.ack(); }); setupCommandListener(widgetId, () => navigate(0)); + return () => { + unsubscribe(widgetId, conf.topic.reel); + cleanupCommandListener(widgetId); + }; }, [widgetId]); useEffect(() => { @@ -89,7 +98,7 @@ export default function ReelWidget({}) { const scroll = () => { glide.go(">"); glide.go(">"); - } + }; console.log(`selected: ${selected}`); if (iteration === 1) { console.log(`setActive to ${selected}`); @@ -117,13 +126,14 @@ export default function ReelWidget({}) { const selectionColor = findSetting(settings, "selectionColor", "green"); const slideStyle = { borderColor: borderColor, + alignItems: "stretch", }; const backgroundImage = findSetting(settings, "backgroundImage", ""); - function calcItemStyle(option: string){ + function calcItemStyle(option: string) { const style = {}; style.borderColor = borderColor; - if (highlight && active === option){ + if (highlight && active === option) { style.backgroundColor = selectionColor; } else { if (backgroundImage) { @@ -131,7 +141,7 @@ export default function ReelWidget({}) { style.backgroundImage = `url(${process.env.REACT_APP_FILE_API_ENDPOINT}/files/${backgroundImage})`; } } - log.debug({style}, "calculated style for slide item"); + log.debug({ style }, "calculated style for slide item"); return style; } @@ -149,16 +159,14 @@ export default function ReelWidget({}) { {options.map((option) => (
  • {option}
  • diff --git a/src/socket.ts b/src/socket.ts index 27f877c..7c5fced 100644 --- a/src/socket.ts +++ b/src/socket.ts @@ -47,6 +47,8 @@ function subscribe(id: string, topic: string, onMessage: messageCallbackType) { function unsubscribe(id: string, topic: string){ log.info(`Deleting subscription ${id} with topic ${topic}`); socket.unsubscribe(`${id}-${topic}`); + const existingListenerIndex = listeners.findIndex(listener => listener.id === id && listener.topic === topic); + listeners.splice(existingListenerIndex, 1); } function setupCommandListener(widgetId: string, reloadFn: Function) { @@ -61,6 +63,12 @@ function setupCommandListener(widgetId: string, reloadFn: Function) { } }); } + +function cleanupCommandListener(widgetId: string){ + unsubscribe(widgetId, "/topic/commands"); +} + + function publish(topic: string, payload: any) { socket.publish({ destination: topic, @@ -68,4 +76,4 @@ function publish(topic: string, payload: any) { }); } -export { socket, subscribe, unsubscribe, setupCommandListener, publish }; +export { socket, subscribe, unsubscribe, setupCommandListener, cleanupCommandListener, publish };