Files
sendou.ink/apps/web-react/app/features/scanner/components/EventsSummary.tsx

66 lines
2.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* One light line summarizing raw detections as per-type counts, with a
* toggle for their event card feed. Callers pass only events not covered
* by a match card — a fallback for detections not yet grouped, hidden
* entirely once everything lives in a match.
*/
import { DEATH_EVENT_TYPE } from "@sendou/scanner-core/detectors/death/index";
import { MAP_START_EVENT_TYPE } from "@sendou/scanner-core/detectors/map-start/index";
import { MINIMAP_EVENT_TYPE } from "@sendou/scanner-core/detectors/minimap/index";
import { OBJECTIVE_EVENT_TYPE } from "@sendou/scanner-core/detectors/objective/index";
import { SCOREBOARD_EVENT_TYPE } from "@sendou/scanner-core/detectors/scoreboard/index";
import { SCOREBOARD_BATTLE_LOG_EVENT_TYPE } from "@sendou/scanner-core/detectors/scoreboard-battle-log/index";
import { SCOREBOARD_BATTLE_LOG_REPLAY_EVENT_TYPE } from "@sendou/scanner-core/detectors/scoreboard-battle-log-replay/index";
import { SCOREBOARD_OWN_EVENT_TYPE } from "@sendou/scanner-core/detectors/scoreboard-own/index";
import * as R from "remeda";
import styles from "./EventsSummary.module.css";
import { EventTypeIcon } from "./EventTypeIcon";
const EVENT_TYPE_LABELS: Record<string, string> = {
[MAP_START_EVENT_TYPE]: "map start",
[DEATH_EVENT_TYPE]: "death",
[MINIMAP_EVENT_TYPE]: "minimap",
[OBJECTIVE_EVENT_TYPE]: "objective",
[SCOREBOARD_EVENT_TYPE]: "scoreboard",
[SCOREBOARD_BATTLE_LOG_REPLAY_EVENT_TYPE]: "replay scoreboard",
[SCOREBOARD_BATTLE_LOG_EVENT_TYPE]: "battle log",
[SCOREBOARD_OWN_EVENT_TYPE]: "own result",
};
export function EventsSummary({
events,
open,
onToggle,
}: {
events: ReadonlyArray<{ type: string }>;
open: boolean;
onToggle: () => void;
}) {
const counts = R.countBy(events, (event) => event.type);
const sorted = Object.entries(counts).toSorted((a, b) => b[1] - a[1]);
return (
<div className={styles.summary}>
{sorted.map(([type, count]) => {
const label = EVENT_TYPE_LABELS[type] ?? type;
return (
<span
key={type}
className={styles.type}
title={`${count} ${label}${count === 1 ? "" : "s"}`}
>
<span className={styles.icon}>
<EventTypeIcon type={type} />
</span>
×{count}
</span>
);
})}
<button type="button" className={styles.toggle} onClick={onToggle}>
{open ? "Hide events" : "Show events"}
</button>
</div>
);
}