mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 23:58:36 -05:00
83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import type { MainWeaponId } from "@sendou/in-game-lists/types";
|
|
import {
|
|
DEATH_EVENT_TYPE,
|
|
type DeathData,
|
|
} from "@sendou/scanner-core/detectors/death/index";
|
|
import clsx from "clsx";
|
|
import { Ability } from "~/components/Ability";
|
|
import { WeaponImage } from "~/components/Image";
|
|
import styles from "./DeathCard.module.css";
|
|
import eventCardStyles from "./EventCard.module.css";
|
|
import { FrameThumb } from "./FrameThumb";
|
|
import { useEventTimeFormatter } from "./format";
|
|
import { weaponLabel } from "./labels";
|
|
import { MetaPills } from "./MetaChips";
|
|
|
|
export function DeathCard(props: {
|
|
t: number;
|
|
confidence: number;
|
|
data: DeathData;
|
|
thumbnail?: string;
|
|
detectedAt?: number;
|
|
/** lazy loader for the exact analyzed frame — enables fixture export */
|
|
getFrame?: () => Promise<Blob | null | undefined>;
|
|
onInspect?: () => void;
|
|
}) {
|
|
const { t, confidence, data, thumbnail, detectedAt, getFrame, onInspect } =
|
|
props;
|
|
const weaponName = weaponLabel(data.weaponType, data.weaponId);
|
|
const formatDetectedAt = useEventTimeFormatter();
|
|
return (
|
|
<div className={eventCardStyles.card}>
|
|
<div className={eventCardStyles.meta}>
|
|
<MetaPills
|
|
t={t}
|
|
confidence={confidence}
|
|
type={DEATH_EVENT_TYPE}
|
|
label="death"
|
|
/>
|
|
{detectedAt ? <span>{formatDetectedAt(detectedAt)}</span> : null}
|
|
<FrameThumb
|
|
thumbnail={thumbnail}
|
|
getFrame={getFrame}
|
|
onInspect={onInspect}
|
|
fixture={{ data, type: "Death" }}
|
|
/>
|
|
</div>
|
|
<div className={clsx(eventCardStyles.teams, eventCardStyles.death)}>
|
|
<div className={eventCardStyles.team}>
|
|
<div className={styles.body}>
|
|
{data.weaponId !== null && data.weaponType === "MAIN" ? (
|
|
<WeaponImage
|
|
weaponSplId={data.weaponId as MainWeaponId}
|
|
variant="build"
|
|
size={28}
|
|
className={eventCardStyles.weaponIcon}
|
|
/>
|
|
) : null}
|
|
<div className={styles.info}>
|
|
<span className={styles.name}>
|
|
splatted by <b>{data.name ?? "?"}</b>
|
|
</span>
|
|
<span className={styles.weapon}>{weaponName ?? "?"}</span>
|
|
</div>
|
|
<div className={styles.abilities}>
|
|
{data.abilities.map((row, i) => (
|
|
<div key={i} className={styles.gear}>
|
|
{row.map((id, j) => (
|
|
<Ability
|
|
key={j}
|
|
ability={id}
|
|
size={j === 0 ? "SUBTINY" : "TINY"}
|
|
/>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|