From 4571d141e6ca4d6b5b560f05311bf7e238151c34 Mon Sep 17 00:00:00 2001 From: Mark Greene Date: Fri, 10 Jul 2026 16:03:05 +1200 Subject: [PATCH 1/2] Fix crash on repeated HE shell clicks in Tankopedia armor viewer --- .../Armor/components/ShotDisplay.tsx | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/website/src/components/Armor/components/ShotDisplay.tsx b/packages/website/src/components/Armor/components/ShotDisplay.tsx index 2cf2335db..3a4c39b63 100644 --- a/packages/website/src/components/Armor/components/ShotDisplay.tsx +++ b/packages/website/src/components/Armor/components/ShotDisplay.tsx @@ -63,10 +63,10 @@ export function ShotDisplay() { outlineMaterial, ).computeLineDistances(); - splashRadiusWrapper.current.add(outline); + splashRadiusWrapper.current?.add(outline); return () => { - splashRadiusWrapper.current.remove(outline); + splashRadiusWrapper.current?.remove(outline); }; } }); @@ -283,17 +283,23 @@ function Animator({ const tracerT1 = t % 1; const tracerT2 = (t + 0.5) % 1; - inTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT1 - 0.5), 1); - inTracer.current.position.set(0, (1 - tracerT1) * inLength, 0); + if (inTracer.current) { + inTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT1 - 0.5), 1); + inTracer.current.position.set(0, (1 - tracerT1) * inLength, 0); - if (outTracer.current) { - outTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT2 - 0.5), 1); - outTracer.current.position.set(0, tracerT2 * outLength, 0); + if (outTracer.current) { + outTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT2 - 0.5), 1); + outTracer.current.position.set(0, tracerT2 * outLength, 0); + } + + invalidate(); } - invalidate(); - - if (shot.splashRadius !== undefined) { + if ( + shot.splashRadius !== undefined && + splashRadiusWrapper.current && + splashRadiusMaterial.current + ) { if (animationStartTime === null) animationStartTime = t; const scale = From 46937693a0532f832219853d2337e7fbdc2c288a Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Sat, 11 Jul 2026 17:09:38 -0500 Subject: [PATCH 2/2] implement nullable refs in a type-safe manner --- .../components/Armor/components/ShotDisplay.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/website/src/components/Armor/components/ShotDisplay.tsx b/packages/website/src/components/Armor/components/ShotDisplay.tsx index 3a4c39b63..ab24a95ad 100644 --- a/packages/website/src/components/Armor/components/ShotDisplay.tsx +++ b/packages/website/src/components/Armor/components/ShotDisplay.tsx @@ -42,10 +42,10 @@ const TRACER_THIN = TRACER_THICK / 2; export function ShotDisplay() { const shot = Tankopedia.use((state) => state.shot); - const inTracer = useRef(null!); - const outTracer = useRef(null!); - const splashRadiusWrapper = useRef(null!); - const splashRadiusMaterial = useRef(null!); + const inTracer = useRef(null); + const outTracer = useRef(null); + const splashRadiusWrapper = useRef(null); + const splashRadiusMaterial = useRef(null); const { locale } = useLocale(); useEffect(() => { @@ -255,11 +255,11 @@ export function ShotDisplay() { } interface AnimatorProps { - inTracer: RefObject; - outTracer: RefObject; + inTracer: RefObject; + outTracer: RefObject; - splashRadiusWrapper: RefObject; - splashRadiusMaterial: RefObject; + splashRadiusWrapper: RefObject; + splashRadiusMaterial: RefObject; inLength: number; outLength: number;