diff --git a/src/components/gamgee-app/gamgee-app.module.css b/src/components/gamgee-app/gamgee-app.module.css index f842503..2ac6f05 100644 --- a/src/components/gamgee-app/gamgee-app.module.css +++ b/src/components/gamgee-app/gamgee-app.module.css @@ -11,7 +11,7 @@ gap: 16px; } -.providerContainer { +.stingConfigGroup { display: flex; flex-direction: column; gap: 12px; diff --git a/src/components/gamgee-app/gamgee-app.tsx b/src/components/gamgee-app/gamgee-app.tsx index 3425a99..a7a4c2a 100644 --- a/src/components/gamgee-app/gamgee-app.tsx +++ b/src/components/gamgee-app/gamgee-app.tsx @@ -8,6 +8,7 @@ import { MenuItem, Select, SelectChangeEvent, + TextField, } from "@mui/material"; import { ManualMetadataProvider } from "../manual-metadata-provider/manual-metadata-provider.tsx"; import { PlexMetadataProvider } from "../plex-metadata-provider/plex-metadata-provider.tsx"; @@ -27,6 +28,9 @@ export const GamgeeApp = () => { const [metadata, setMetadata] = useState(null); const { mediaTimerProperties, mediaTimerActions } = useMediaTimer(24); + const [swordOnWebhookUrl, setSwordOnWebhookUrl] = useState(""); + const [swordOffWebhookUrl, setSwordOffWebhookUrl] = useState(""); + const providerLabelId = useId(); const providerLabel = "Metadata Provider"; @@ -55,25 +59,43 @@ export const GamgeeApp = () => { differences={metadata.edition.differences} chapters={metadata.edition.chapters} timestamp={mediaTimerProperties.timestamp} + swordOnWebhookUrl={swordOnWebhookUrl} + swordOffWebhookUrl={swordOffWebhookUrl} /> )} {capitalize(mediaTimerProperties.state)} - - {providerLabel} - - -
+
+ + setSwordOnWebhookUrl(newUrlEvent.target.value) + } + /> + + setSwordOffWebhookUrl(newUrlEvent.target.value) + } + /> + + {providerLabel} + + +
+
{metadataProvider === "Manual" && ( )} diff --git a/src/components/sting-component/sting-component.tsx b/src/components/sting-component/sting-component.tsx index f218fab..0fa7eef 100644 --- a/src/components/sting-component/sting-component.tsx +++ b/src/components/sting-component/sting-component.tsx @@ -1,39 +1,27 @@ -import { useCallback, useEffect, useState } from "react"; import styles from "./sting-component.module.css"; import { StingSword } from "../sting-sword/sting-sword"; import { EditionChapter, EditionDifferenceData } from "../../movies/movies.ts"; import dayjsUtc from "../../utils/dayjs-config.ts"; +import { useIsGlowing } from "./useIsGlowing.ts"; +import { useCallWebhook } from "./useCallWebhook.ts"; interface StingComponentProps { differences: EditionDifferenceData[]; chapters: EditionChapter[]; timestamp: number; + swordOnWebhookUrl: string; + swordOffWebhookUrl: string; } export const StingComponent = ({ differences, chapters, timestamp, + swordOnWebhookUrl, + swordOffWebhookUrl, }: StingComponentProps) => { - const [swordIsGlowing, setSwordIsGlowing] = useState(false); - - const getDifference = useCallback( - (time: number) => - differences.find( - (difference) => - difference.start_time_ms < time && difference.end_time_ms > time, - ), - [differences], - ); - - useEffect(() => { - const maybeDifference = getDifference(timestamp); - if (maybeDifference && !swordIsGlowing) { - setSwordIsGlowing(true); - } else if (!maybeDifference && swordIsGlowing) { - setSwordIsGlowing(false); - } - }, [getDifference, swordIsGlowing, timestamp]); + const swordIsGlowing = useIsGlowing(differences, timestamp); + useCallWebhook(swordIsGlowing, swordOnWebhookUrl, swordOffWebhookUrl); const chapter = chapters.findLast((c) => c.start_time_ms <= timestamp); const chapterInfo = chapter?.title ?? "Unknown Chapter"; diff --git a/src/components/sting-component/useCallWebhook.ts b/src/components/sting-component/useCallWebhook.ts new file mode 100644 index 0000000..a266ed2 --- /dev/null +++ b/src/components/sting-component/useCallWebhook.ts @@ -0,0 +1,22 @@ +import { useEffect } from "react"; + +export const useCallWebhook = ( + swordIsGlowing: boolean, + swordOnWebhookUrl: string, + swordOffWebhookUrl: string, +) => { + const callWebhook = (webhookUrl: string | undefined) => { + if (!webhookUrl) { + return; + } + fetch(webhookUrl, { method: "POST" }); + }; + + useEffect(() => { + if (swordIsGlowing) { + callWebhook(swordOnWebhookUrl); + } else { + callWebhook(swordOffWebhookUrl); + } + }, [swordIsGlowing, swordOffWebhookUrl, swordOnWebhookUrl]); +}; diff --git a/src/components/sting-component/useIsGlowing.ts b/src/components/sting-component/useIsGlowing.ts new file mode 100644 index 0000000..25eca49 --- /dev/null +++ b/src/components/sting-component/useIsGlowing.ts @@ -0,0 +1,25 @@ +import { useCallback, useEffect, useState } from "react"; +import { EditionDifferenceData } from "../../movies/movies"; + +export const useIsGlowing = ( + differences: EditionDifferenceData[], + timestamp: number, +) => { + const [swordIsGlowing, setSwordIsGlowing] = useState(false); + + const getDifference = useCallback( + (time: number) => + differences.find( + (difference) => + difference.start_time_ms < time && difference.end_time_ms > time, + ), + [differences], + ); + + useEffect(() => { + const maybeDifference = getDifference(timestamp); + setSwordIsGlowing(!!maybeDifference); + }, [getDifference, swordIsGlowing, timestamp]); + + return swordIsGlowing; +};