|
@@ -9,6 +9,7 @@ import { usePlayers } from "../../../hooks/useGameInfo";
|
|
|
import styles from "./KillFeed.module.css";
|
|
|
import hitmarker from "../../../assets/hitmarker.svg";
|
|
|
import hitsound from "../../../assets/hitsound.wav";
|
|
|
+import critsound from "../../../assets/critsound.mp3";
|
|
|
|
|
|
// okay, in an ideal world this would be part of the game store or something
|
|
|
// and it would get properly managed by reactive state
|
|
@@ -21,6 +22,7 @@ const KillFeed = () => {
|
|
|
const playerName = usePlayerName();
|
|
|
const gameId = useGameId();
|
|
|
const players = usePlayers();
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
if (players?.find(({ currentRound }) => currentRound === null)) {
|
|
|
dispatch.goToSummary();
|
|
@@ -28,6 +30,7 @@ const KillFeed = () => {
|
|
|
}, [players]);
|
|
|
const [shownItemsState, setShownItemsState] = useState(shownItems);
|
|
|
const [display, setDisplay] = useState([]);
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
const toDisplay =
|
|
|
players
|
|
@@ -44,32 +47,36 @@ const KillFeed = () => {
|
|
|
!shownItemsState.has(`${gameId}-${name}-${round}`)
|
|
|
) ?? [];
|
|
|
setDisplay(toDisplay);
|
|
|
+
|
|
|
+ toDisplay.forEach(({ name, round }) => {
|
|
|
+ shownItems.add(`${gameId}-${name}-${round}`);
|
|
|
+ });
|
|
|
const timeout = setTimeout(() => {
|
|
|
- toDisplay.forEach(({ name, round }) => {
|
|
|
- shownItems.add(`${gameId}-${name}-${round}`);
|
|
|
- });
|
|
|
setShownItemsState(new Set(shownItems));
|
|
|
- }, 5000);
|
|
|
+ }, 8000);
|
|
|
return () => {
|
|
|
clearTimeout(timeout);
|
|
|
};
|
|
|
}, [shownItemsState, gameId, players, playerName]);
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
- if (!muted) {
|
|
|
- display.forEach(() => {
|
|
|
- const audio = new Audio(hitsound);
|
|
|
- audio.volume = 0.5;
|
|
|
- // delay up to half a second so overlapping sounds better
|
|
|
- const delayedPlay = () =>
|
|
|
- setTimeout(() => audio.play(), Math.random() * 500);
|
|
|
- audio.addEventListener("canplaythrough", delayedPlay);
|
|
|
- // clean up after ourselves in the hopes that the browser actually deletes this audio element
|
|
|
- audio.addEventListener("ended", () =>
|
|
|
- audio.removeEventListener("canplaythrough", delayedPlay)
|
|
|
- );
|
|
|
- });
|
|
|
+ if (muted) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ display.forEach(({ score }) => {
|
|
|
+ const audio = new Audio(score >= 4950 ? critsound : hitsound);
|
|
|
+ audio.volume = score >= 4950 ? 0.25 : 0.5;
|
|
|
+ // delay up to half a second so overlapping sounds better
|
|
|
+ const delayedPlay = () =>
|
|
|
+ setTimeout(() => audio.play(), Math.random() * 500);
|
|
|
+ audio.addEventListener("canplaythrough", delayedPlay);
|
|
|
+ // clean up after ourselves in the hopes that the browser actually deletes this audio element
|
|
|
+ audio.addEventListener("ended", () =>
|
|
|
+ audio.removeEventListener("canplaythrough", delayedPlay)
|
|
|
+ );
|
|
|
+ });
|
|
|
}, [display, muted]);
|
|
|
+
|
|
|
return (
|
|
|
<>
|
|
|
{display.map(() => (
|