Audio via ref, DownloadButton key, highlight by token not index, deleteDownload onClick

This commit is contained in:
2025-01-02 14:55:26 -06:00
parent d71433fa52
commit bb224eed43

View File

@@ -3,21 +3,36 @@ import DownloadButton from "@/components/DownloadButton";
import Emboldened from "@/components/Emboldened"; import Emboldened from "@/components/Emboldened";
import useSocket from "@/components/useSocket"; import useSocket from "@/components/useSocket";
import { cn, plural, toHex, type ClassValue } from "@/util"; import { cn, plural, toHex, type ClassValue } from "@/util";
import { useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
type DemoProps = { type DemoProps = {
class?: ClassValue; class?: ClassValue;
}; };
const Demo = ({ class: className }: DemoProps) => { const Demo = ({ class: className }: DemoProps) => {
const { id, downloads, executables } = useSocket(); const audioRef = useRef<HTMLAudioElement | null>(null);
const { id, downloads, executables, deleteDownload } = useSocket({
notify: (token) => {
audioRef.current!.play();
highlight(token);
},
});
// TODO: Toasts // TODO: Toasts
const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null); const [highlightedToken, setHighlightedToken] = useState<number | null>(null);
const highlightedTimeoutRef = useRef<NodeJS.Timeout | null>(null); const highlightedTimeoutRef = useRef<NodeJS.Timeout | null>(null);
function highlight(index: number) { useEffect(() => {
setHighlightedIndex(index); audioRef.current = new Audio("/notify.wav");
audioRef.current.volume = 1;
return () => {
audioRef.current!.remove();
};
}, []);
function highlight(token: number) {
setHighlightedToken(token);
if (highlightedTimeoutRef.current != null) { if (highlightedTimeoutRef.current != null) {
clearTimeout(highlightedTimeoutRef.current); clearTimeout(highlightedTimeoutRef.current);
@@ -25,7 +40,7 @@ const Demo = ({ class: className }: DemoProps) => {
highlightedTimeoutRef.current = setTimeout(() => { highlightedTimeoutRef.current = setTimeout(() => {
highlightedTimeoutRef.current = null; highlightedTimeoutRef.current = null;
setHighlightedIndex(null); setHighlightedToken(null);
}, 1250); }, 1250);
} }
@@ -46,25 +61,25 @@ const Demo = ({ class: className }: DemoProps) => {
</Emboldened>{" "} </Emboldened>{" "}
known {plural("download", downloads?.length ?? 0)}. known {plural("download", downloads?.length ?? 0)}.
</p> </p>
<div className="flex flex-wrap justify-center gap-y-2.5"> <div className="flex flex-wrap justify-center gap-y-2.5 gap-x-2">
<DownloadButton <DownloadButton
key="download"
disabled={executables == null} disabled={executables == null}
buildLog={"https://railway.com"} buildLog={"https://railway.com"}
executables={executables} executables={executables}
/> />
{downloads?.map((download, i) => ( {downloads?.map((download, i) => (
<Badge <Badge
key={download.token}
className={cn( className={cn(
"transition-colors border hover:border-zinc-500 duration-100 ease-in border-transparent", "transition-colors border hover:border-zinc-500 duration-100 ease-in border-transparent",
{ {
"!border-zinc-300 dark:bg-zinc-600": i === highlightedIndex, "bg-zinc-500 animate-pulse-border border-white text-zinc-50":
highlightedToken === download.token,
} }
)} )}
onClick={function onClick() { onClick={() => {
highlight(i); deleteDownload(download.token);
const audio = new Audio("/notify.wav");
audio.volume = 0.5;
audio.play();
}} }}
> >
{toHex(download.token)} {toHex(download.token)}