From bfc2cec7d43eb8eaa46dd3f91084932381257059 Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Sun, 15 Mar 2026 16:19:35 -0400 Subject: refactor: excalidraw-app/ --- excalidraw-app/collab/CollabError.tsx | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 excalidraw-app/collab/CollabError.tsx (limited to 'excalidraw-app/collab/CollabError.tsx') diff --git a/excalidraw-app/collab/CollabError.tsx b/excalidraw-app/collab/CollabError.tsx new file mode 100644 index 0000000..76828cf --- /dev/null +++ b/excalidraw-app/collab/CollabError.tsx @@ -0,0 +1,54 @@ +import { Tooltip } from "@excalidraw/excalidraw/components/Tooltip"; +import { warning } from "@excalidraw/excalidraw/components/icons"; +import clsx from "clsx"; +import { useEffect, useRef, useState } from "react"; +import { atom } from "../app-jotai"; + +import "./CollabError.scss"; + +type ErrorIndicator = { + message: string | null; + /** used to rerun the useEffect responsible for animation */ + nonce: number; +}; + +export const collabErrorIndicatorAtom = atom({ + message: null, + nonce: 0, +}); + +const CollabError = ({ collabError }: { collabError: ErrorIndicator }) => { + const [isAnimating, setIsAnimating] = useState(false); + const clearAnimationRef = useRef(0); + + useEffect(() => { + setIsAnimating(true); + clearAnimationRef.current = window.setTimeout(() => { + setIsAnimating(false); + }, 1000); + + return () => { + window.clearTimeout(clearAnimationRef.current); + }; + }, [collabError.message, collabError.nonce]); + + if (!collabError.message) { + return null; + } + + return ( + +
+ {warning} +
+
+ ); +}; + +CollabError.displayName = "CollabError"; + +export default CollabError; -- cgit v1.2.3