KillFeed.jsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { useEffect, useState } from "react";
  2. import { dispatch, useGameId } from "../../../domain/gameStore";
  3. import { usePlayers } from "../../../hooks/useGameInfo";
  4. import styles from "./GamePanel.module.css";
  5. // okay, in an ideal world this would be part of the game store or something
  6. // and it would get properly managed by reactive state
  7. // but also, this totally works as is, and the only downside is it might potentially grow too big
  8. // but that only happens if someone plays that many gun games without ever leaving the window
  9. const shownItems = new Set();
  10. const KillFeed = () => {
  11. const gameId = useGameId();
  12. const players = usePlayers();
  13. useEffect(() => {
  14. if (players?.find(({ currentRound }) => currentRound === null)) {
  15. dispatch.goToSummary();
  16. }
  17. }, [players]);
  18. const [shownItemsState, setShownItemsState] = useState(shownItems);
  19. const [display, setDisplay] = useState([]);
  20. useEffect(() => {
  21. const toDisplay =
  22. players
  23. ?.flatMap(({ name, guesses }) =>
  24. Object.entries(guesses).map(([round, { score }]) => ({
  25. name,
  26. round,
  27. score,
  28. }))
  29. )
  30. ?.filter(
  31. ({ name, round }) =>
  32. !shownItemsState.has(`${gameId}-${name}-${round}`)
  33. ) ?? [];
  34. setDisplay(toDisplay);
  35. const timeouts = [];
  36. toDisplay.forEach(({ name, round }) => {
  37. timeouts.push(
  38. setTimeout(() => {
  39. shownItems.add(`${gameId}-${name}-${round}`);
  40. setShownItemsState(new Set(shownItems));
  41. }, 5000)
  42. );
  43. });
  44. return () => {
  45. timeouts.forEach(t => clearTimeout(t));
  46. };
  47. }, [shownItemsState, gameId, players]);
  48. return (
  49. <div className={styles.killFeed}>
  50. {display.map(({ name, round, score }) => (
  51. <span key={`${name}-${round}`} className={styles.killFeedItem}>
  52. <span className={styles.killFeedName}>{name}</span>{" "}
  53. {score >= 4950 ? "🎯" : "🖱️"} 🗺️ {round}
  54. </span>
  55. ))}
  56. </div>
  57. );
  58. };
  59. export default KillFeed;