From f61e71077ff680398273aba89dd8ad7432e11095 Mon Sep 17 00:00:00 2001 From: eeshm Date: Mon, 1 Dec 2025 18:41:23 +0530 Subject: [PATCH 1/3] fix: rive crash in New Folder/Subfolder dialogs and folder components (#1409) --- .../dashboard/caps/components/Folders.tsx | 60 +++++++++++++++---- .../caps/components/NewFolderDialog.tsx | 17 +++++- .../[id]/components/SubfolderDialog.tsx | 11 +++- 3 files changed, 74 insertions(+), 14 deletions(-) diff --git a/apps/web/app/(org)/dashboard/caps/components/Folders.tsx b/apps/web/app/(org)/dashboard/caps/components/Folders.tsx index 4c10c09440..64193387f9 100644 --- a/apps/web/app/(org)/dashboard/caps/components/Folders.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/Folders.tsx @@ -29,11 +29,19 @@ export const NormalFolder = React.forwardRef< () => ({ play: (animationName: string) => { if (!rive) return; - rive.play(animationName); + try { + rive.play(animationName); + } catch (error) { + console.warn("Failed to play folder animation", error); + } }, stop: () => { if (!rive) return; - rive.stop(); + try { + rive.stop(); + } catch (error) { + console.warn("Failed to stop folder animation", error); + } }, }), [rive], @@ -66,11 +74,19 @@ export const BlueFolder = React.forwardRef< () => ({ play: (animationName: string) => { if (!rive) return; - rive.play(animationName); + try { + rive.play(animationName); + } catch (error) { + console.warn("Failed to play folder animation", error); + } }, stop: () => { if (!rive) return; - rive.stop(); + try { + rive.stop(); + } catch (error) { + console.warn("Failed to stop folder animation", error); + } }, }), [rive], @@ -98,11 +114,19 @@ export const RedFolder = React.forwardRef< () => ({ play: (animationName: string) => { if (!rive) return; - rive.play(animationName); + try { + rive.play(animationName); + } catch (error) { + console.warn("Failed to play folder animation", error); + } }, stop: () => { if (!rive) return; - rive.stop(); + try { + rive.stop(); + } catch (error) { + console.warn("Failed to stop folder animation", error); + } }, }), [rive], @@ -130,11 +154,19 @@ export const YellowFolder = React.forwardRef< () => ({ play: (animationName: string) => { if (!rive) return; - rive.play(animationName); + try { + rive.play(animationName); + } catch (error) { + console.warn("Failed to play folder animation", error); + } }, stop: () => { if (!rive) return; - rive.stop(); + try { + rive.stop(); + } catch (error) { + console.warn("Failed to stop folder animation", error); + } }, }), [rive], @@ -177,11 +209,19 @@ export const AllFolders = React.forwardRef( () => ({ play: (animationName: string) => { if (!rive) return; - rive.play(animationName); + try { + rive.play(animationName); + } catch (error) { + console.warn("Failed to play folder animation", error); + } }, stop: () => { if (!rive) return; - rive.stop(); + try { + rive.stop(); + } catch (error) { + console.warn("Failed to stop folder animation", error); + } }, }), [rive], diff --git a/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx b/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx index 065f2e4ea9..04c69a85b8 100644 --- a/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx @@ -83,8 +83,14 @@ export const NewFolderDialog: React.FC = ({ src: "/rive/dashboard.riv", }); - useEffect(() => { - if (!open) setSelectedColor(null); + useEffect(() => { + if (!open) { + setSelectedColor(null); + // Stop all animations when dialog closes + Object.values(folderRefs.current).forEach((ref) => { + ref.current?.stop(); + }); + } }, [open]); const folderRefs = useRef( @@ -156,22 +162,27 @@ export const NewFolderDialog: React.FC = ({ setSelectedColor(option.value); }} onMouseEnter={() => { + if (!riveFile) return; const folderRef = folderRefs.current[option.value]?.current; if (!folderRef) return; folderRef.stop(); folderRef.play("folder-open"); }} onMouseLeave={() => { + if (!riveFile) return; const folderRef = folderRefs.current[option.value]?.current; if (!folderRef) return; folderRef.stop(); folderRef.play("folder-close"); }} > - {option.component( + {riveFile && option.component( riveFile as RiveFile, folderRefs.current[option.value], )} + {!riveFile && ( +
+ )}

{option.label}

); diff --git a/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx b/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx index 3fdc67ba35..9c0e3fd8ee 100644 --- a/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx +++ b/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx @@ -91,6 +91,10 @@ export const SubfolderDialog: React.FC = ({ if (!open) { setSelectedColor(null); setFolderName(""); + // Stop any running animations when the dialog closes + Object.values(folderRefs.current).forEach((ref) => { + ref.current?.stop(); + }); } }, [open]); @@ -163,21 +167,26 @@ export const SubfolderDialog: React.FC = ({ setSelectedColor(option.value); }} onMouseEnter={() => { + if (!riveFile) return; const folderRef = folderRefs.current[option.value]?.current; if (!folderRef) return; folderRef.stop(); folderRef.play("folder-open"); }} onMouseLeave={() => { + if (!riveFile) return; const folderRef = folderRefs.current[option.value]?.current; if (!folderRef) return; folderRef.stop(); folderRef.play("folder-close"); }} > - {option.component( + {riveFile && option.component( riveFile as RiveFile, folderRefs.current[option.value], + )} + {!riveFile && ( +
)}

{option.label}

From 645376e5fee7b6d13b457f43d7d349db1f2ff2b1 Mon Sep 17 00:00:00 2001 From: eeshm Date: Mon, 1 Dec 2025 19:03:30 +0530 Subject: [PATCH 2/3] chore: format files --- .../dashboard/caps/components/NewFolderDialog.tsx | 13 +++++++------ .../folder/[id]/components/SubfolderDialog.tsx | 7 ++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx b/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx index 04c69a85b8..fc2bdb0d4b 100644 --- a/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx @@ -83,8 +83,8 @@ export const NewFolderDialog: React.FC = ({ src: "/rive/dashboard.riv", }); - useEffect(() => { - if (!open) { + useEffect(() => { + if (!open) { setSelectedColor(null); // Stop all animations when dialog closes Object.values(folderRefs.current).forEach((ref) => { @@ -176,10 +176,11 @@ export const NewFolderDialog: React.FC = ({ folderRef.play("folder-close"); }} > - {riveFile && option.component( - riveFile as RiveFile, - folderRefs.current[option.value], - )} + {riveFile && + option.component( + riveFile as RiveFile, + folderRefs.current[option.value], + )} {!riveFile && (
)} diff --git a/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx b/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx index 9c0e3fd8ee..042aea776e 100644 --- a/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx +++ b/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx @@ -181,9 +181,10 @@ export const SubfolderDialog: React.FC = ({ folderRef.play("folder-close"); }} > - {riveFile && option.component( - riveFile as RiveFile, - folderRefs.current[option.value], + {riveFile && + option.component( + riveFile as RiveFile, + folderRefs.current[option.value], )} {!riveFile && (
From 47b699e89bcdfe794e25aa6341f8b2b984196ce0 Mon Sep 17 00:00:00 2001 From: eeshm Date: Mon, 1 Dec 2025 19:10:09 +0530 Subject: [PATCH 3/3] chore: remove comments --- apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx | 1 - .../(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx b/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx index fc2bdb0d4b..886e9055fe 100644 --- a/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx @@ -86,7 +86,6 @@ export const NewFolderDialog: React.FC = ({ useEffect(() => { if (!open) { setSelectedColor(null); - // Stop all animations when dialog closes Object.values(folderRefs.current).forEach((ref) => { ref.current?.stop(); }); diff --git a/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx b/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx index 042aea776e..1cc7070b14 100644 --- a/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx +++ b/apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx @@ -91,7 +91,6 @@ export const SubfolderDialog: React.FC = ({ if (!open) { setSelectedColor(null); setFolderName(""); - // Stop any running animations when the dialog closes Object.values(folderRefs.current).forEach((ref) => { ref.current?.stop(); });