Skip to content
Merged
2 changes: 1 addition & 1 deletion src/components/gamgee-app/gamgee-app.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
gap: 16px;
}

.providerContainer {
.stingConfigGroup {
display: flex;
flex-direction: column;
gap: 12px;
Expand Down
54 changes: 38 additions & 16 deletions src/components/gamgee-app/gamgee-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -27,6 +28,9 @@ export const GamgeeApp = () => {
const [metadata, setMetadata] = useState<EditionMetadata | null>(null);
const { mediaTimerProperties, mediaTimerActions } = useMediaTimer(24);

const [swordOnWebhookUrl, setSwordOnWebhookUrl] = useState<string>("");
const [swordOffWebhookUrl, setSwordOffWebhookUrl] = useState<string>("");

const providerLabelId = useId();
const providerLabel = "Metadata Provider";

Expand Down Expand Up @@ -55,25 +59,43 @@ export const GamgeeApp = () => {
differences={metadata.edition.differences}
chapters={metadata.edition.chapters}
timestamp={mediaTimerProperties.timestamp}
swordOnWebhookUrl={swordOnWebhookUrl}
swordOffWebhookUrl={swordOffWebhookUrl}
/>
)}
<Alert severity="info">{capitalize(mediaTimerProperties.state)}</Alert>
<FormControl>
<InputLabel id={providerLabelId}>{providerLabel}</InputLabel>
<Select
value={metadataProvider}
labelId={providerLabelId}
label={providerLabel}
onChange={handleMetadataProviderChange}
>
{metadataProviders.map((provider) => (
<MenuItem key={provider} value={provider}>
{provider}
</MenuItem>
))}
</Select>
</FormControl>
<div className={styles.providerContainer}>
<div className={styles.stingConfigGroup}>
<TextField
value={swordOnWebhookUrl}
label="Sword On Webhook"
onChange={(newUrlEvent) =>
setSwordOnWebhookUrl(newUrlEvent.target.value)
}
/>
<TextField
value={swordOffWebhookUrl}
label="Sword Off Webhook"
onChange={(newUrlEvent) =>
setSwordOffWebhookUrl(newUrlEvent.target.value)
}
/>
<FormControl>
<InputLabel id={providerLabelId}>{providerLabel}</InputLabel>
<Select
value={metadataProvider}
labelId={providerLabelId}
label={providerLabel}
onChange={handleMetadataProviderChange}
>
{metadataProviders.map((provider) => (
<MenuItem key={provider} value={provider}>
{provider}
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div className={styles.stingConfigGroup}>
{metadataProvider === "Manual" && (
<ManualMetadataProvider {...metadataProviderProps} />
)}
Expand Down
28 changes: 8 additions & 20 deletions src/components/sting-component/sting-component.tsx
Original file line number Diff line number Diff line change
@@ -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<boolean>(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";
Expand Down
22 changes: 22 additions & 0 deletions src/components/sting-component/useCallWebhook.ts
Original file line number Diff line number Diff line change
@@ -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]);
};
25 changes: 25 additions & 0 deletions src/components/sting-component/useIsGlowing.ts
Original file line number Diff line number Diff line change
@@ -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<boolean>(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;
};